added drawing pad
parent
593041b19b
commit
9f0cc75a3f
|
@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
|
|||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion flutter.compileSdkVersion
|
||||
compileSdkVersion 34
|
||||
ndkVersion "25.1.8937393"
|
||||
|
||||
compileOptions {
|
||||
|
@ -47,6 +47,7 @@ android {
|
|||
applicationId "com.app.rpass"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.unit2">
|
||||
package="com.example.unit2"
|
||||
>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
|
||||
<application
|
||||
android:label="uniT App"
|
||||
android:name="${applicationName}"
|
||||
|
@ -16,7 +20,8 @@ android:authorities = "${applicationId}.fileprovider"
|
|||
android:exported = "false"
|
||||
android:grantUriPermissions = "true"
|
||||
android:name = "androidx.core.content.FileProvider"
|
||||
android:usesCleartextTraffic="true">
|
||||
android:usesCleartextTraffic="true"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
|
||||
<meta-data
|
||||
android:name = "android.support.FILE_PROVIDER_PATHS"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 443 B |
|
@ -1,8 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/model/passo/floor_sketch.dart';
|
||||
import 'package:unit2/sevices/offline/offline_passo/admin/sql_services/sql_services.dart';
|
||||
import 'package:unit2/sevices/passo/building/building_services.dart';
|
||||
import '../../../../../model/offline/offline_profile.dart';
|
||||
|
@ -15,8 +17,11 @@ import '../../../../../model/passo/property_assessment.dart';
|
|||
import '../../../../../model/passo/property_info.dart';
|
||||
import '../../../../../model/passo/structureMaterial.dart';
|
||||
import '../../../../../model/passo/todo.dart';
|
||||
import '../../../../../model/profile/basic_information/primary-information.dart';
|
||||
import '../../../../../sevices/offline/offline_passo/building/property_owner_info_service.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import 'package:path/path.dart';
|
||||
// as http;
|
||||
|
||||
import '../../../../../utils/urls.dart';
|
||||
|
@ -71,6 +76,7 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
});
|
||||
|
||||
on<FetchTodos>((event, emit) async {
|
||||
emit(PropertyOwnerInfoLoading());
|
||||
propertyOwner = await SQLServices.instance.readAllBldgOwner();
|
||||
emit(PropertyInfoLoaded(propertyInfos: propertyOwner));
|
||||
});
|
||||
|
@ -82,80 +88,56 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
|
||||
on<DeleteTodo>((event, emit) async {
|
||||
await SQLServices.instance.deleteBldgOwner(id: event.id);
|
||||
add(const FetchTodos());
|
||||
});
|
||||
on<UploadBuildingFaas>(((event, emit) async {
|
||||
emit(UploadBuildingFaasLoading());
|
||||
// Directly fetch and emit new data rather than triggering another event
|
||||
try {
|
||||
List<PropertyInfo> propertyOwner =
|
||||
await SQLServices.instance.readAllBldgOwner();
|
||||
for (PropertyInfo infos in propertyOwner) {
|
||||
//General Description
|
||||
emit(PropertyOwnerInfoLoading());
|
||||
propertyOwner.clear(); // Clear the current list
|
||||
propertyOwner =
|
||||
await SQLServices.instance.readAllBldgOwner(); // Refetch data
|
||||
emit(PropertyInfoLoaded(
|
||||
propertyInfos: propertyOwner)); // Emit new state with updated data
|
||||
} catch (error) {
|
||||
// emit((error.toString())); // Handle potential errors
|
||||
print(error.toString());
|
||||
}
|
||||
});
|
||||
|
||||
Future<Map<String, dynamic>> _prepareBuildingDetails(
|
||||
UploadBuildingFaas event, PropertyInfo infos) async {
|
||||
// Fetch data
|
||||
List<Map<String, dynamic>> genDesc =
|
||||
await SQLServices.instance.getGeneralDescription(infos.id);
|
||||
List<GeneralDesc> genDescList =
|
||||
genDesc.map((map) => GeneralDesc.fromJson2(map)).toList();
|
||||
|
||||
GeneralDesc firstGenDesc = genDescList.first;
|
||||
|
||||
//Location
|
||||
List<Map<String, dynamic>> loc =
|
||||
await SQLServices.instance.getLocation(infos.id);
|
||||
|
||||
List<BldgLoc> locList =
|
||||
loc.map((map) => BldgLoc.fromJson2(map)).toList();
|
||||
|
||||
BldgLoc firstLoc = locList.first;
|
||||
|
||||
//Land Refeernce
|
||||
List<Map<String, dynamic>> landRef =
|
||||
await SQLServices.instance.getLandRef(infos.id);
|
||||
|
||||
List<LandRef> landRefList =
|
||||
landRef.map((map) => LandRef.fromJson2(map)).toList();
|
||||
|
||||
LandRef firstLandRef = landRefList.first;
|
||||
|
||||
//Assessment
|
||||
List<Map<String, dynamic>> assessment =
|
||||
await SQLServices.instance.getBldgAssessment(infos.id);
|
||||
|
||||
List<PropertyAssessment> assessList = assessment
|
||||
.map((map) => PropertyAssessment.fromJson2(map))
|
||||
.toList();
|
||||
|
||||
PropertyAssessment firstAssess = assessList.first;
|
||||
|
||||
//Structural Materials
|
||||
List<Map<String, dynamic>> strucMat =
|
||||
await SQLServices.instance.getStructuralMaterials(infos.id);
|
||||
List<StructureMaterials> strcuMatList =
|
||||
strucMat.map((map) => StructureMaterials.fromJson2(map)).toList();
|
||||
|
||||
StructureMaterials firstStructMat = strcuMatList.first;
|
||||
|
||||
//Additional Items
|
||||
List<Map<String, dynamic>> addItems =
|
||||
await SQLServices.instance.getAdditionalItems(infos.id);
|
||||
List<AdditionalItems> addItemsList =
|
||||
addItems.map((map) => AdditionalItems.fromJson(map)).toList();
|
||||
|
||||
//BLDG Structure
|
||||
List<Map<String, dynamic>> bldgStructure =
|
||||
await SQLServices.instance.getBuildingAndStructure(infos.id);
|
||||
List<BldgAndStructure> bldgStructureList = bldgStructure
|
||||
.map((map) => BldgAndStructure.fromJson(map))
|
||||
.toList();
|
||||
|
||||
// Parse data
|
||||
GeneralDesc firstGenDesc = GeneralDesc.fromJson2(genDesc.first);
|
||||
BldgLoc firstLoc = BldgLoc.fromJson2(loc.first);
|
||||
LandRef firstLandRef = LandRef.fromJson2(landRef.first);
|
||||
PropertyAssessment firstAssess =
|
||||
PropertyAssessment.fromJson2(assessment.first);
|
||||
StructureMaterials firstStructMat =
|
||||
StructureMaterials.fromJson2(strucMat.first);
|
||||
|
||||
// Prepare details
|
||||
DateTime dateIssued = DateTime.parse(firstGenDesc.dateIssued!);
|
||||
|
||||
final details = {
|
||||
"assessed_by_id": event.offlineProfile.id.toString(),
|
||||
"assessed_by_name": event.offlineProfile.firstName,
|
||||
"date_created": "{{currentTimestamp}}",
|
||||
"date_modified": "{{currentTimestamp}}",
|
||||
"trans_code": infos.transCode,
|
||||
"tdn": '222',
|
||||
"trans_code": '08887',
|
||||
"tdn": infos.tdn,
|
||||
"pin": infos.pin,
|
||||
"fname": infos.fname,
|
||||
"mname": infos.mname,
|
||||
|
@ -195,11 +177,9 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
"bldgappr_generaldesc.date_issued": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstGenDesc.dateIssued!)),
|
||||
"bldgappr_generaldesc.cct": null,
|
||||
"bldgappr_generaldesc.cert_completion_issued":
|
||||
DateFormat("yyyy-MM-dd")
|
||||
"bldgappr_generaldesc.cert_completion_issued": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstGenDesc.certCompletionIssued!)),
|
||||
"bldgappr_generaldesc.cert_occupancy_issued":
|
||||
DateFormat("yyyy-MM-dd")
|
||||
"bldgappr_generaldesc.cert_occupancy_issued": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstGenDesc.certOccupancyIssued!)),
|
||||
"bldgappr_generaldesc.date_completed": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstGenDesc.dateCompleted!)),
|
||||
|
@ -211,8 +191,7 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
"bldgappr_generaldesc.area_2ndfloor": firstGenDesc.area2Ndfloor,
|
||||
"bldgappr_generaldesc.area_3rdfloor": firstGenDesc.area3Rdfloor,
|
||||
"bldgappr_generaldesc.area_4thfloor": firstGenDesc.area4Thfloor,
|
||||
"bldgappr_generaldesc.total_floor_area":
|
||||
firstGenDesc.totalFloorArea,
|
||||
"bldgappr_generaldesc.total_floor_area": firstGenDesc.totalFloorArea,
|
||||
"bldgappr_generaldesc.floor_sketch": null,
|
||||
"bldgappr_generaldesc.actual_use": firstGenDesc.actualUse,
|
||||
"bldgappr_generaldesc.unit_value": firstGenDesc.unitValue,
|
||||
|
@ -222,19 +201,16 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
"bldgappr_struct_materials.foundation": firstStructMat.foundation,
|
||||
"bldgappr_struct_materials.columns": firstStructMat.columns,
|
||||
"bldgappr_struct_materials.beams": firstStructMat.beams,
|
||||
"bldgappr_struct_materials.truss_framing":
|
||||
firstStructMat.trussFraming,
|
||||
"bldgappr_struct_materials.truss_framing": firstStructMat.trussFraming,
|
||||
"bldgappr_struct_materials.roof": firstStructMat.roof,
|
||||
"bldgappr_struct_materials.flooring": firstStructMat.flooring,
|
||||
"bldgappr_struct_materials.walls": firstStructMat.walls,
|
||||
"bldgappr_struct_materials.others": firstStructMat.others,
|
||||
"bldgappr_struct_materials.gen_code": "5TH",
|
||||
"bldgappr_property_assessment.date_created": "{{currentTimestamp}}",
|
||||
"bldgappr_property_assessment.date_modified":
|
||||
"{{currentTimestamp}}",
|
||||
"bldgappr_property_assessment.date_modified": "{{currentTimestamp}}",
|
||||
"bldgappr_property_assessment.actual_use": firstAssess.actualUse,
|
||||
"bldgappr_property_assessment.market_value":
|
||||
firstAssess.marketValue,
|
||||
"bldgappr_property_assessment.market_value": firstAssess.marketValue,
|
||||
"bldgappr_property_assessment.assessment_level":
|
||||
firstAssess.assessmentLevel,
|
||||
"bldgappr_property_assessment.assessed_value":
|
||||
|
@ -261,15 +237,13 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
firstAssess.approvedbyName,
|
||||
"bldgappr_property_assessment.approvedby_designation":
|
||||
firstAssess.approvedbyDesignation,
|
||||
"bldgappr_property_assessment.approvedby_date":
|
||||
DateFormat("yyyy-MM-dd")
|
||||
"bldgappr_property_assessment.approvedby_date": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstAssess.approvedbyDate!)),
|
||||
"bldgappr_property_assessment.memoranda": firstAssess.memoranda,
|
||||
"bldgappr_property_assessment.note": firstAssess.note,
|
||||
"bldgappr_property_assessment.swornstatement_no":
|
||||
firstAssess.swornstatementNo,
|
||||
"bldgappr_property_assessment.date_received":
|
||||
DateFormat("yyyy-MM-dd")
|
||||
"bldgappr_property_assessment.date_received": DateFormat("yyyy-MM-dd")
|
||||
.format(DateTime.parse(firstAssess.dateReceived!)),
|
||||
"bldgappr_property_assessment.entry_date_assessment":
|
||||
DateFormat("yyyy-MM-dd")
|
||||
|
@ -293,10 +267,11 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
"bldgappr_rec_supersededass.gen_code": "5TH"
|
||||
};
|
||||
|
||||
// http.Response response =
|
||||
// (await BuildingServices.instance.add(details))!;
|
||||
// print(response.body);
|
||||
return details;
|
||||
}
|
||||
|
||||
Future<void> _postAdditionalItems(
|
||||
Map<String, dynamic> datas, PropertyInfo infos) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
Map<String, String> headers = {
|
||||
|
@ -305,15 +280,14 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
'X-Client-Secret': xClientKeySecret
|
||||
};
|
||||
|
||||
Response details_response = await post(
|
||||
Uri.parse(
|
||||
'https://${Url.instance.host()}/api/rptass_app/bldgappr_details/'),
|
||||
headers: headers,
|
||||
body: jsonEncode(details));
|
||||
List<Map<String, dynamic>> addItems =
|
||||
await SQLServices.instance.getAdditionalItems(infos.id);
|
||||
|
||||
final datas = json.decode(details_response.body);
|
||||
List<AdditionalItems> addItemsList =
|
||||
addItems.map((map) => AdditionalItems.fromJson(map)).toList();
|
||||
|
||||
for (AdditionalItems items in addItemsList) {
|
||||
// Populate AdditionalItems model here
|
||||
final addItems = AdditionalItems(
|
||||
id: 1,
|
||||
bldgapprDetailsId: datas['data']['id'],
|
||||
|
@ -333,14 +307,30 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
secondhandUnitval: items.secondhandUnitval,
|
||||
actualUse: items.actualUse,
|
||||
genCode: "5TH");
|
||||
Response add_response = await post(
|
||||
Response addResponse = await post(
|
||||
Uri.parse(
|
||||
'https://${Url.instance.host()}/api/rptass_app/additional_items/'),
|
||||
'http://${Url.instance.host()}/api/rptass_app/additional_items/'),
|
||||
headers: headers,
|
||||
body: jsonEncode(addItems));
|
||||
print('add_response.body');
|
||||
print(add_response.body);
|
||||
print(addResponse.body);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _postBuildingStructures(
|
||||
Map<String, dynamic> datas, PropertyInfo infos) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret
|
||||
};
|
||||
|
||||
List<Map<String, dynamic>> bldgStructures =
|
||||
await SQLServices.instance.getBuildingAndStructure(infos.id);
|
||||
|
||||
List<BldgAndStructure> bldgStructureList =
|
||||
bldgStructures.map((map) => BldgAndStructure.fromJson(map)).toList();
|
||||
for (BldgAndStructure structure in bldgStructureList) {
|
||||
final bldgStruc = BldgAndStructure(
|
||||
id: 1,
|
||||
|
@ -358,21 +348,157 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
|
|||
adjustedMarketValue: structure.adjustedMarketValue,
|
||||
genCode: '5TH',
|
||||
buccPercentage: structure.buccPercentage);
|
||||
print(bldgStruc.toJson());
|
||||
Response response = await post(
|
||||
Uri.parse(
|
||||
'https://${Url.instance.host()}/api/rptass_app/bldgappr_structure/'),
|
||||
'http://${Url.instance.host()}/api/rptass_app/bldgappr_structure/'),
|
||||
headers: headers,
|
||||
body: jsonEncode(bldgStruc));
|
||||
print('response.body');
|
||||
print(response.body);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Response> _postBuildingDetails(Map<String, dynamic> details) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret
|
||||
};
|
||||
|
||||
return await post(
|
||||
Uri.parse(
|
||||
'http://${Url.instance.host()}/api/rptass_app/bldgappr_details/'),
|
||||
headers: headers,
|
||||
body: jsonEncode(details));
|
||||
}
|
||||
|
||||
Future<Response> _postFloorSketch(
|
||||
Map<String, dynamic> details, file) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
|
||||
// Construct the headers for the request
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret,
|
||||
};
|
||||
|
||||
// Create a MultipartRequest
|
||||
var request = MultipartRequest(
|
||||
'POST',
|
||||
Uri.parse(
|
||||
'http://${Url.instance.host()}/api/rptass_app/bldgappr_sketch/'),
|
||||
);
|
||||
|
||||
// Add the headers to the request
|
||||
request.headers.addAll(headers);
|
||||
|
||||
// Add JSON data as a field
|
||||
// Add individual fields to the request
|
||||
details.forEach((key, value) {
|
||||
request.fields[key] = value.toString();
|
||||
});
|
||||
|
||||
// Add the floor sketch image file, if it exists
|
||||
|
||||
var fileName = basename(file);
|
||||
request.files.add(
|
||||
await MultipartFile.fromPath(
|
||||
'floor_sketch', // Field name in the API
|
||||
file,
|
||||
filename: fileName,
|
||||
),
|
||||
);
|
||||
|
||||
// Send the request and get the response
|
||||
var streamedResponse = await request.send();
|
||||
return await Response.fromStream(streamedResponse);
|
||||
}
|
||||
|
||||
Future<void> _uploadImage(data, infos) async {
|
||||
// Create a map with the required fields
|
||||
|
||||
List<Map<String, dynamic>> floorSketch =
|
||||
await SQLServices.instance.getFloorSketch(infos.id);
|
||||
|
||||
// Parse data
|
||||
FloorSketch firstFs = FloorSketch.fromJson(floorSketch.first);
|
||||
var file = File(firstFs.floorSketch!);
|
||||
Map<String, dynamic> detailsMap = {
|
||||
"bldgappr_details_id": data['data']['id'], // int8 NOT NULL
|
||||
"date_created": DateTime.now().toIso8601String(), // timestamptz NULL
|
||||
"floor_sketch": firstFs.floorSketch!, // text NULL
|
||||
"gen_code": "5TH", // varchar(20) NOT NULL
|
||||
};
|
||||
|
||||
try {
|
||||
Response response = await _postFloorSketch(detailsMap, file.path);
|
||||
print(response.body);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
print('Upload successful');
|
||||
} else {
|
||||
print('Upload failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
on<UploadBuildingFaas>((event, emit) async {
|
||||
emit(UploadBuildingFaasLoading());
|
||||
try {
|
||||
List<PropertyInfo> propertyOwner =
|
||||
await SQLServices.instance.readAllBldgOwner();
|
||||
|
||||
for (PropertyInfo infos in propertyOwner) {
|
||||
final details = await _prepareBuildingDetails(event, infos);
|
||||
|
||||
Response detailsResponse = await _postBuildingDetails(details);
|
||||
final datas = json.decode(detailsResponse.body);
|
||||
|
||||
print(datas);
|
||||
|
||||
await _postAdditionalItems(datas, infos);
|
||||
await _postBuildingStructures(datas, infos);
|
||||
await _uploadImage(datas, infos);
|
||||
|
||||
if (detailsResponse.statusCode == 201) {
|
||||
final detailsInfo = PropertyInfo(
|
||||
id: infos.id,
|
||||
transCode: infos.transCode,
|
||||
assessedById: infos.assessedById,
|
||||
assessedByName: infos.assessedByName,
|
||||
tdn: infos.tdn,
|
||||
pin: infos.pin,
|
||||
fname: infos.fname,
|
||||
mname: infos.mname,
|
||||
bday: infos.bday,
|
||||
lname: infos.lname,
|
||||
address: infos.address,
|
||||
telno: infos.telno,
|
||||
tin: infos.tin,
|
||||
adminUser: infos.adminUser,
|
||||
adminAddress: infos.adminAddress,
|
||||
adminTin: infos.adminTin,
|
||||
adminTelno: infos.adminTelno,
|
||||
faasType: "Building",
|
||||
dateSynced:
|
||||
DateFormat('MM/dd/yyyy hh:mm a').format(DateTime.now()));
|
||||
|
||||
await SQLServices.instance.updateBldgOwner(infos.id, detailsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
propertyOwner = await SQLServices.instance.readAllBldgOwner();
|
||||
emit(PropertyInfoLoaded(propertyInfos: propertyOwner));
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
emit(PropertyOwnerInfoErrorState(errorMessage: e.toString()));
|
||||
}
|
||||
}));
|
||||
;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ Future main() async {
|
|||
SOS = await Hive.openBox<dynamic>('soscontacts');
|
||||
OFFLINE = await Hive.openBox<dynamic>('offline');
|
||||
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft])
|
||||
.then((_) {
|
||||
runApp(MyApp());
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//
|
||||
// final additionalItems = additionalItemsFromJson(jsonString);
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
AdditionalItems additionalItemsFromJson(String str) =>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//
|
||||
// final classComponents = classComponentsFromJson(jsonString);
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
ClassComponentsOffline classComponentsFromJson(String str) =>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//
|
||||
// final classComponents = classComponentsFromJson(jsonString);
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
ClassComponents classComponentsFromJson(String str) =>
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// To parse this JSON data, do
|
||||
//
|
||||
// final floorSketch = floorSketchFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
FloorSketch floorSketchFromJson(String str) =>
|
||||
FloorSketch.fromJson(json.decode(str));
|
||||
|
||||
String floorSketchToJson(FloorSketch data) => json.encode(data.toJson());
|
||||
|
||||
class FloorSketch {
|
||||
final int? bldgapprDetailsId;
|
||||
final String? dateCreated;
|
||||
final String? floorSketch;
|
||||
final String? genCode;
|
||||
|
||||
FloorSketch({
|
||||
this.bldgapprDetailsId,
|
||||
this.dateCreated,
|
||||
this.floorSketch,
|
||||
this.genCode,
|
||||
});
|
||||
|
||||
FloorSketch copy(
|
||||
{int? bldgapprDetailsId,
|
||||
String? dateCreated,
|
||||
String? floorSketch,
|
||||
String? genCode}) {
|
||||
return FloorSketch(
|
||||
bldgapprDetailsId: bldgapprDetailsId ?? this.bldgapprDetailsId,
|
||||
dateCreated: dateCreated ?? this.dateCreated,
|
||||
floorSketch: floorSketch ?? this.floorSketch,
|
||||
genCode: genCode ?? this.genCode,
|
||||
);
|
||||
}
|
||||
|
||||
FloorSketch copyWith({
|
||||
int? bldgapprDetailsId,
|
||||
String? dateCreated,
|
||||
String? floorSketch,
|
||||
String? genCode,
|
||||
}) =>
|
||||
FloorSketch(
|
||||
bldgapprDetailsId: bldgapprDetailsId ?? this.bldgapprDetailsId,
|
||||
dateCreated: dateCreated ?? this.dateCreated,
|
||||
floorSketch: floorSketch ?? this.floorSketch,
|
||||
genCode: genCode ?? this.genCode,
|
||||
);
|
||||
|
||||
factory FloorSketch.fromJson(Map<String, dynamic> json) => FloorSketch(
|
||||
bldgapprDetailsId: json["bldgappr_details_id"],
|
||||
dateCreated: json["date_created"],
|
||||
floorSketch: json["floor_sketch"],
|
||||
genCode: json["gen_code"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"bldgappr_details_id": bldgapprDetailsId,
|
||||
"date_created": dateCreated,
|
||||
"floor_sketch": floorSketch,
|
||||
"gen_code": genCode,
|
||||
};
|
||||
}
|
|
@ -31,9 +31,10 @@ class PropertyInfo {
|
|||
final String? adminTin;
|
||||
final String? faasType;
|
||||
final String? genCode;
|
||||
final String? dateSynced;
|
||||
|
||||
PropertyInfo({
|
||||
this.id,
|
||||
PropertyInfo(
|
||||
{this.id,
|
||||
this.assessedById,
|
||||
this.assessedByName,
|
||||
this.dateCreated,
|
||||
|
@ -54,10 +55,10 @@ class PropertyInfo {
|
|||
this.adminTin,
|
||||
this.faasType,
|
||||
this.genCode,
|
||||
});
|
||||
this.dateSynced});
|
||||
|
||||
PropertyInfo copy({
|
||||
int? id,
|
||||
PropertyInfo copy(
|
||||
{int? id,
|
||||
String? assessedById,
|
||||
String? assessedByName,
|
||||
String? dateCreated,
|
||||
|
@ -75,7 +76,7 @@ class PropertyInfo {
|
|||
String? adminTin,
|
||||
String? faasType,
|
||||
String? genCode,
|
||||
}) =>
|
||||
String? dateSynced}) =>
|
||||
PropertyInfo(
|
||||
id: id ?? this.id,
|
||||
assessedById: assessedById ?? this.assessedById,
|
||||
|
@ -98,7 +99,7 @@ class PropertyInfo {
|
|||
adminTin: adminTin ?? this.adminTin,
|
||||
faasType: faasType ?? this.faasType,
|
||||
genCode: genCode ?? this.genCode,
|
||||
);
|
||||
dateSynced: dateSynced ?? this.dateSynced);
|
||||
|
||||
factory PropertyInfo.fromJson(Map<String, dynamic> json) => PropertyInfo(
|
||||
id: json["id"],
|
||||
|
@ -126,7 +127,7 @@ class PropertyInfo {
|
|||
adminTin: json["admin_tin"],
|
||||
faasType: json["faas_type"],
|
||||
genCode: json["gen_code"],
|
||||
);
|
||||
dateSynced: json["dateSynced"]);
|
||||
|
||||
factory PropertyInfo.fromJson2(Map<String, dynamic> json) => PropertyInfo(
|
||||
id: json["id"],
|
||||
|
@ -146,7 +147,6 @@ class PropertyInfo {
|
|||
lname: json["lname"],
|
||||
bday: json["bday"],
|
||||
address: json["address"],
|
||||
|
||||
telno: json["telno"],
|
||||
tin: json["tin"],
|
||||
adminUser: json["adminUser"],
|
||||
|
@ -155,7 +155,7 @@ class PropertyInfo {
|
|||
adminTin: json["adminTin"],
|
||||
faasType: json["faasType"],
|
||||
genCode: json["genCode"],
|
||||
);
|
||||
dateSynced: json["dateSynced"]);
|
||||
|
||||
factory PropertyInfo.fromMap(Map<String, dynamic> map) => PropertyInfo(
|
||||
id: map["id"],
|
||||
|
@ -178,7 +178,8 @@ class PropertyInfo {
|
|||
adminTelno: map["adminTelno"],
|
||||
adminTin: map["adminTin"],
|
||||
faasType: map["faasType"],
|
||||
genCode: map["genCode"]);
|
||||
genCode: map["genCode"],
|
||||
dateSynced: map["dateSynced"]);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
|
@ -202,5 +203,6 @@ class PropertyInfo {
|
|||
"admin_tin": adminTin,
|
||||
"faas_type": faasType,
|
||||
"gen_code": genCode,
|
||||
"dateSynced": dateSynced
|
||||
};
|
||||
}
|
||||
|
|
|
@ -40,6 +40,13 @@ class UnitConstruct {
|
|||
);
|
||||
}
|
||||
|
||||
UnitConstruct.defaultConstruct()
|
||||
: id = 0,
|
||||
bldgType = 'defaultType',
|
||||
building = 'defaultBuilding',
|
||||
unitValue = '0',
|
||||
genCode = 'defaultGenCode';
|
||||
|
||||
factory UnitConstruct.fromJson2(Map<String, dynamic> json) => UnitConstruct(
|
||||
id: json["id"],
|
||||
bldgType: json["bldgType"],
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// final familyBackground = familyBackgroundFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:ffi';
|
||||
|
||||
import '../utils/category.dart';
|
||||
import '../utils/position.dart';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:fluttericon/entypo_icons.dart';
|
||||
|
@ -38,11 +37,13 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
|
|||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
const DocInfo(title: "4427", subTitle: documentId),
|
||||
const CostumDivider(),
|
||||
const DocInfo(title: "Purchase of Diesel", subTitle: documentTitle),
|
||||
const DocInfo(
|
||||
title: "Purchase of Diesel", subTitle: documentTitle),
|
||||
const CostumDivider(),
|
||||
const DocInfo(title: "N/A", subTitle: documentSubject),
|
||||
const CostumDivider(),
|
||||
const DocInfo(title: "Request for Quotation", subTitle: documentType),
|
||||
const DocInfo(
|
||||
title: "Request for Quotation", subTitle: documentType),
|
||||
const CostumDivider(),
|
||||
Form(
|
||||
child: Column(children: [
|
||||
|
@ -60,7 +61,7 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
|
|||
),
|
||||
Text(
|
||||
sourceRemarks,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
|
@ -72,8 +73,8 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
|
|||
autovalidateMode:
|
||||
AutovalidateMode.onUserInteraction,
|
||||
maxLines: 5,
|
||||
decoration: normalTextFieldStyle(
|
||||
enterRemarks, "..."),
|
||||
decoration:
|
||||
normalTextFieldStyle(enterRemarks, "..."),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
|
@ -123,8 +124,8 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
|
|||
width: double.infinity,
|
||||
height: screenHeight * .06,
|
||||
child: ElevatedButton(
|
||||
style: secondaryBtnStyle(
|
||||
primary, Colors.transparent, Colors.white54),
|
||||
style: secondaryBtnStyle(primary,
|
||||
Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
requestAutoReceipt,
|
||||
style: TextStyle(color: Colors.white),
|
||||
|
|
|
@ -54,7 +54,7 @@ class OfflineModuleScreen extends StatelessWidget {
|
|||
children: state.offlineModules
|
||||
.map((e) => CardLabel(
|
||||
icon: FontAwesome5.eye,
|
||||
title: "Field Surveyor",
|
||||
title: "Rpass Offline",
|
||||
ontap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: ((context) {
|
||||
|
|
|
@ -46,22 +46,22 @@ class _AdminMainScreen extends State<AdminMainScreen> {
|
|||
backgroundColor: primary,
|
||||
title: const Text("PASSO Admin"),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
textStyle: const TextStyle(fontSize: 15),
|
||||
),
|
||||
onPressed: () async {
|
||||
try {
|
||||
GlobalSyncService().syncAllData();
|
||||
} catch (e) {
|
||||
// Handle any errors that might occur during the API call or database insertion.
|
||||
print("Error: $e");
|
||||
}
|
||||
},
|
||||
child: const Text('SYNC'),
|
||||
),
|
||||
],
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// style: TextButton.styleFrom(
|
||||
// textStyle: const TextStyle(fontSize: 15),
|
||||
// ),
|
||||
// onPressed: () async {
|
||||
// try {
|
||||
// GlobalSyncService().syncAllData();
|
||||
// } catch (e) {
|
||||
// // Handle any errors that might occur during the API call or database insertion.
|
||||
// print("Error: $e");
|
||||
// }
|
||||
// },
|
||||
// child: const Text('SYNC'),
|
||||
// ),
|
||||
// ],
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
|
@ -82,7 +82,7 @@ class _AdminMainScreen extends State<AdminMainScreen> {
|
|||
const Divider(),
|
||||
MainMenu(
|
||||
icon: Elusive.wrench,
|
||||
title: "Barangays",
|
||||
title: "Barangay",
|
||||
onTap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
|
|
|
@ -21,7 +21,7 @@ class _BarangayAdminPage extends State<BarangayAdminPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: primary,
|
||||
title: const Text("Municipaities"),
|
||||
title: const Text("Barangay"),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
TextButton(
|
||||
|
|
|
@ -29,7 +29,7 @@ class _UnitConstructionAdminPage extends State<UnitConstructionAdminPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: primary,
|
||||
title: const Text("Unit Construction"),
|
||||
title: const Text("Structural Types"),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
TextButton(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
|
@ -14,6 +16,18 @@ import '../../../../../model/passo/unit_construct.dart';
|
|||
import '../../../../../theme-data.dart/form-style.dart';
|
||||
import '../../../../../widgets/passo/custom_formBuilder_fields.dart';
|
||||
|
||||
// Function to get stored building type
|
||||
Future<UnitConstruct> getStoredBldgType() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? jsonString = prefs.getString('selected_bldg_type');
|
||||
if (jsonString != null) {
|
||||
Map<String, dynamic> json = jsonDecode(jsonString);
|
||||
return UnitConstruct.fromJson(json);
|
||||
}
|
||||
// Return a default UnitConstruct if no data is found
|
||||
return UnitConstruct.defaultConstruct();
|
||||
}
|
||||
|
||||
class AddBuildingAndStructureOffline extends StatefulWidget {
|
||||
final OfflineProfile offlineProfile;
|
||||
AddBuildingAndStructureOffline(this.offlineProfile);
|
||||
|
@ -33,7 +47,8 @@ class _AddBuildingAndStructureOffline
|
|||
|
||||
_AddBuildingAndStructureOffline()
|
||||
: now = DateTime.now(),
|
||||
formatter = DateFormat.yMMMMd('en_US').format(DateTime.now());
|
||||
formatter = DateFormat.yMMMMd('en_US').format(DateTime.now()),
|
||||
_unitConstruct = UnitConstruct.defaultConstruct();
|
||||
|
||||
final actual_use = [
|
||||
"Residential",
|
||||
|
@ -47,6 +62,22 @@ class _AddBuildingAndStructureOffline
|
|||
String _structureType = "";
|
||||
double _areaValue = 0;
|
||||
double _depRate = 0;
|
||||
UnitConstruct _unitConstruct;
|
||||
bool _isLoading = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadData();
|
||||
}
|
||||
|
||||
Future<void> _loadData() async {
|
||||
UnitConstruct unitConstruct = await getStoredBldgType();
|
||||
setState(() {
|
||||
_unitConstruct = unitConstruct;
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
double _totalMarketValue(unitBase, bldgArea) {
|
||||
return unitBase * bldgArea;
|
||||
|
@ -62,6 +93,14 @@ class _AddBuildingAndStructureOffline
|
|||
return marketVal - depAmount;
|
||||
}
|
||||
|
||||
void assignSelectedBldgValues() async {
|
||||
UnitConstruct? storedBldgType = await getStoredBldgType();
|
||||
_unitBase = double.parse(storedBldgType!.unitValue);
|
||||
_structureType = '${storedBldgType.bldgType} - ${storedBldgType.building}';
|
||||
|
||||
formKey.currentState!.patchValue({'unit_value': storedBldgType.unitValue});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocConsumer<BuildingAndStructureBloc, BuildingAndStructureState>(
|
||||
|
@ -91,12 +130,34 @@ class _AddBuildingAndStructureOffline
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: FormBuilderDropdown<String?>(
|
||||
name: 'actual_use',
|
||||
autofocus: false,
|
||||
decoration: normalTextFieldStyle("Actual Use", ""),
|
||||
items: actual_use
|
||||
.map((item) => DropdownMenuItem(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
assignSelectedBldgValues();
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: SizedBox(
|
||||
height: 45,
|
||||
child: SearchField(
|
||||
enabled: false,
|
||||
itemHeight: 70,
|
||||
suggestions: state.unit
|
||||
.map((UnitConstruct unit) =>
|
||||
|
@ -115,7 +176,10 @@ class _AddBuildingAndStructureOffline
|
|||
errorText: "This field is required"),
|
||||
|
||||
searchInputDecoration: normalTextFieldStyle(
|
||||
"Structure Type", "")
|
||||
_unitConstruct!.bldgType +
|
||||
' - ' +
|
||||
_unitConstruct!.building,
|
||||
"")
|
||||
.copyWith(
|
||||
suffixIcon:
|
||||
const Icon(Icons.arrow_drop_down)),
|
||||
|
@ -123,15 +187,7 @@ class _AddBuildingAndStructureOffline
|
|||
focusNode: focus,
|
||||
suggestionState: Suggestion.expand,
|
||||
onSuggestionTap: (unit) {
|
||||
setState(() {
|
||||
_unitBase =
|
||||
double.parse(unit.item!.unitValue);
|
||||
_structureType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
|
||||
formKey.currentState!.patchValue(
|
||||
{'unit_value': unit.item?.unitValue});
|
||||
});
|
||||
setState(() {});
|
||||
focus.unfocus();
|
||||
},
|
||||
),
|
||||
|
@ -140,19 +196,12 @@ class _AddBuildingAndStructureOffline
|
|||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
customDropDownField(
|
||||
"Actual Use", "", 'actual_use', actual_use),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
child: FormBuilderTextField(
|
||||
name: 'unit_value',
|
||||
decoration: normalTextFieldStyle("Unit Value", ""),
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
keyboardType: TextInputType.phone,
|
||||
onChanged: (value) {
|
||||
// setState(() {
|
||||
// _areaValue = int.parse(value!);
|
||||
|
@ -170,6 +219,7 @@ class _AddBuildingAndStructureOffline
|
|||
name: 'dep_rate',
|
||||
decoration: normalTextFieldStyle(
|
||||
"Depreciation Rate", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
|
@ -186,6 +236,7 @@ class _AddBuildingAndStructureOffline
|
|||
name: 'bldg_area',
|
||||
decoration: normalTextFieldStyle("Area", ""),
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
keyboardType: TextInputType.phone,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_areaValue = double.parse(value!);
|
||||
|
@ -313,7 +364,7 @@ class _AddBuildingAndStructureOffline
|
|||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -332,7 +383,7 @@ class _AddBuildingAndStructureOffline
|
|||
.add(const LoadBuildingAndStructure());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
@ -342,7 +393,7 @@ class _AddBuildingAndStructureOffline
|
|||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
); // Use your actual widget
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
|
@ -11,12 +13,25 @@ import 'package:unit2/bloc/offline/offline_passo/admin/unit_construction/unit_co
|
|||
import 'package:unit2/bloc/offline/offline_passo/building/additional_items_offline/additional_items_offline_bloc.dart';
|
||||
import 'package:unit2/model/offline/offline_profile.dart';
|
||||
import 'package:unit2/model/passo/additional_items.dart';
|
||||
import 'package:unit2/model/passo/class_components%20_offline.dart';
|
||||
import 'package:unit2/model/passo/class_components.dart';
|
||||
import 'package:unit2/model/passo/unit_construct.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
// Function to get stored building type
|
||||
Future<UnitConstruct> getStoredBldgType() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? jsonString = prefs.getString('selected_bldg_type');
|
||||
if (jsonString != null) {
|
||||
Map<String, dynamic> json = jsonDecode(jsonString);
|
||||
return UnitConstruct.fromJson(json);
|
||||
}
|
||||
// Return a default UnitConstruct if no data is found
|
||||
return UnitConstruct.defaultConstruct();
|
||||
}
|
||||
|
||||
class AddExtraItemsOffline extends StatefulWidget {
|
||||
final OfflineProfile offlineProfile;
|
||||
AddExtraItemsOffline(this.offlineProfile);
|
||||
|
@ -28,6 +43,7 @@ class AddExtraItemsOffline extends StatefulWidget {
|
|||
class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
||||
GlobalKey<FormBuilderState> formKey = GlobalKey<FormBuilderState>();
|
||||
final focus = FocusNode();
|
||||
final focusAddItems = FocusNode();
|
||||
bool isPainted = false;
|
||||
bool isSecondHand = false;
|
||||
TextEditingController textEditingController = TextEditingController();
|
||||
|
@ -47,7 +63,26 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
|
||||
_AddExtraItemsOffline()
|
||||
: now = DateTime.now(),
|
||||
formatter = DateFormat.yMMMMd('en_US').format(DateTime.now());
|
||||
formatter = DateFormat.yMMMMd('en_US').format(DateTime.now()),
|
||||
_unitConstruct = UnitConstruct.defaultConstruct();
|
||||
|
||||
UnitConstruct _unitConstruct;
|
||||
|
||||
bool _isLoading = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadData();
|
||||
}
|
||||
|
||||
Future<void> _loadData() async {
|
||||
UnitConstruct unitConstruct = await getStoredBldgType();
|
||||
setState(() {
|
||||
_unitConstruct = unitConstruct;
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
BoxDecoration box1() {
|
||||
return const BoxDecoration(boxShadow: [
|
||||
|
@ -83,6 +118,22 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
}
|
||||
}
|
||||
|
||||
void assignSelectedBldgValues() async {
|
||||
UnitConstruct? storedBldgType = await getStoredBldgType();
|
||||
if (_withoutBUCC) {
|
||||
_unitBase = _unitValue;
|
||||
_structureType =
|
||||
storedBldgType!.bldgType + ' - ' + storedBldgType.building;
|
||||
formKey.currentState!.patchValue({'buccValue': '100'});
|
||||
} else {
|
||||
_unitBase = double.parse(storedBldgType!.unitValue);
|
||||
_structureType =
|
||||
storedBldgType!.bldgType + ' - ' + storedBldgType.building;
|
||||
;
|
||||
formKey.currentState!.patchValue({'unitValue': storedBldgType.unitValue});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AdditionalItemsOfflineBloc, AdditionalItemsOfflineState>(
|
||||
|
@ -123,159 +174,208 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: SizedBox(
|
||||
height: 45,
|
||||
width: 300,
|
||||
child: FormBuilderDropdown(
|
||||
name: 'extra_item',
|
||||
autofocus: false,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Additional Item", ""),
|
||||
items: classes
|
||||
.map((e) => DropdownMenuItem(
|
||||
value: e,
|
||||
child: Text(e.componentName!),
|
||||
))
|
||||
child: SearchField(
|
||||
itemHeight: 70,
|
||||
suggestions: classes
|
||||
.map((ClassComponentsOffline clss) =>
|
||||
SearchFieldListItem(
|
||||
'${clss.componentName}',
|
||||
item: clss,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
'${clss.componentName}',
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
),
|
||||
)))
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
if (value!.minBaseUnitvalPercent !=
|
||||
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
|
||||
searchInputDecoration: normalTextFieldStyle(
|
||||
"Additional Improvements", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
////agency suggestion tap
|
||||
focusNode: focusAddItems,
|
||||
suggestionState: Suggestion.expand,
|
||||
onSuggestionTap: (value) {
|
||||
setState(() {
|
||||
if (value.item!.minBaseUnitvalPercent !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.minBaseUnitvalPercent!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
_unitValue = double.parse(value
|
||||
.item!.minBaseUnitvalPercent!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue':
|
||||
value.minBaseUnitvalPercent
|
||||
'unitValue': value
|
||||
.item!.minBaseUnitvalPercent
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'buccValue': (double.parse(value
|
||||
.item!
|
||||
.minBaseUnitvalPercent!) *
|
||||
100)
|
||||
.toString()
|
||||
});
|
||||
}
|
||||
if (value.maxBaseUnitvalPercent !=
|
||||
if (value.item!.maxBaseUnitvalPercent !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.maxBaseUnitvalPercent!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
_unitValue = double.parse(value
|
||||
.item!.maxBaseUnitvalPercent!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue':
|
||||
value.maxBaseUnitvalPercent
|
||||
'unitValue': value
|
||||
.item!.maxBaseUnitvalPercent
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'buccValue': (double.parse(value
|
||||
.item!
|
||||
.maxBaseUnitvalPercent!) *
|
||||
100)
|
||||
.toString()
|
||||
});
|
||||
}
|
||||
if (value.minUnitvalSqrmtr != '0.00') {
|
||||
if (value.item!.minUnitvalSqrmtr !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.minUnitvalSqrmtr!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.minUnitvalSqrmtr!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.minUnitvalSqrmtr
|
||||
'unitValue':
|
||||
value.item!.minUnitvalSqrmtr
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxUnitvalSqrmtr != '0.00') {
|
||||
if (value.item!.maxUnitvalSqrmtr !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.maxUnitvalSqrmtr!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.maxUnitvalSqrmtr!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.maxUnitvalSqrmtr
|
||||
'unitValue':
|
||||
value.item!.maxUnitvalSqrmtr
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.minAddBaseunitval != '0.00') {
|
||||
if (value.item!.minAddBaseunitval !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.minAddBaseunitval!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.minAddBaseunitval!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.minAddBaseunitval
|
||||
'unitValue':
|
||||
value.item!.minAddBaseunitval
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxAddBaseunitval != '0.00') {
|
||||
if (value.item!.maxAddBaseunitval !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.maxAddBaseunitval!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.maxAddBaseunitval!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.maxAddBaseunitval
|
||||
'unitValue':
|
||||
value.item!.maxAddBaseunitval
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.minDeductBaserate != '0.00') {
|
||||
if (value.item!.minDeductBaserate !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.minDeductBaserate!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.minDeductBaserate!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.minDeductBaserate
|
||||
'unitValue':
|
||||
value.item!.minDeductBaserate
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxDeductBaserate != '0.00') {
|
||||
if (value.item!.maxDeductBaserate !=
|
||||
'0.00') {
|
||||
setState(() {
|
||||
_unitValue = double.parse(
|
||||
value.maxDeductBaserate!);
|
||||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC = value.withoutBucc == 1
|
||||
value.item!.maxDeductBaserate!);
|
||||
_className =
|
||||
value.item!.componentName!;
|
||||
_classId = value.item!.id!;
|
||||
_withoutBUCC =
|
||||
value.item!.withoutBucc == 1
|
||||
? true
|
||||
: false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.maxDeductBaserate
|
||||
'unitValue':
|
||||
value.item!.maxDeductBaserate
|
||||
});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
assignSelectedBldgValues();
|
||||
focusAddItems.unfocus();
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -287,15 +387,20 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
child: SizedBox(
|
||||
height: 45,
|
||||
child: SearchField(
|
||||
enabled: false,
|
||||
itemHeight: 70,
|
||||
suggestions: state.unit
|
||||
.map((UnitConstruct unit) =>
|
||||
SearchFieldListItem(
|
||||
'${unit.bldgType} - ${unit.building}',
|
||||
_unitConstruct.bldgType +
|
||||
' - ' +
|
||||
_unitConstruct.building,
|
||||
item: unit,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
'${unit.bldgType} - ${unit.building!.toUpperCase()}',
|
||||
_unitConstruct.bldgType +
|
||||
' - ' +
|
||||
_unitConstruct.building,
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
),
|
||||
|
@ -306,7 +411,10 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
errorText: "This field is required"),
|
||||
|
||||
searchInputDecoration: normalTextFieldStyle(
|
||||
"Structure Type", "")
|
||||
_unitConstruct.bldgType +
|
||||
' - ' +
|
||||
_unitConstruct.building,
|
||||
"")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
|
@ -314,52 +422,12 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
focusNode: focus,
|
||||
suggestionState: Suggestion.expand,
|
||||
onSuggestionTap: (unit) {
|
||||
setState(() {
|
||||
if (_withoutBUCC) {
|
||||
_unitBase = _unitValue;
|
||||
_structureType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
} else {
|
||||
_unitBase = double.parse(
|
||||
unit.item!.unitValue);
|
||||
_structureType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': unit.item!.unitValue
|
||||
});
|
||||
}
|
||||
});
|
||||
setState(() {});
|
||||
focus.unfocus();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
// Container(
|
||||
// margin: const EdgeInsets.only(
|
||||
// left: 0, top: 10, right: 0, bottom: 0),
|
||||
// child: FormBuilderDropdown(
|
||||
// name: 'struc_type',
|
||||
// autofocus: false,
|
||||
// decoration:
|
||||
// normalTextFieldStyle("Structure Type", ""),
|
||||
// items: widget.unit
|
||||
// .map((e) => DropdownMenuItem(
|
||||
// value: e,
|
||||
// child:
|
||||
// Text(e.bldgType + " - " + e.building),
|
||||
// ))
|
||||
// .toList(),
|
||||
// onChanged: (val) {
|
||||
// setState(() {
|
||||
// _unitBase = double.parse(val!.unitValue);
|
||||
// _structureType = val.bldgType;
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
|
@ -369,6 +437,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
name: 'unitValue',
|
||||
decoration: normalTextFieldStyle(
|
||||
"Unit Value", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator:
|
||||
FormBuilderValidators.compose([]),
|
||||
),
|
||||
|
@ -380,6 +449,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
name: 'buccValue',
|
||||
decoration:
|
||||
normalTextFieldStyle("BUCC", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator:
|
||||
FormBuilderValidators.compose([]),
|
||||
onChanged: (value) {
|
||||
|
@ -414,6 +484,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
name: 'areaValue',
|
||||
decoration:
|
||||
normalTextFieldStyle("Area", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator:
|
||||
FormBuilderValidators.compose([]),
|
||||
onChanged: (value) {
|
||||
|
@ -425,56 +496,6 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
),
|
||||
],
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
// FormBuilderTextField(
|
||||
// name: 'depRate',
|
||||
// decoration:
|
||||
// normalTextFieldStyle("Depreciation Rate", ""),
|
||||
// validator: FormBuilderValidators.compose([]),
|
||||
// onChanged: (value) {
|
||||
// setState(() {
|
||||
// _depValue = double.parse(value!);
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// FormBuilderTextField(
|
||||
// name: 'marketValue',
|
||||
// decoration: normalTextFieldStyle(
|
||||
// NumberFormat.currency(
|
||||
// locale: 'en-PH', symbol: "₱")
|
||||
// .format(_totalMarketValue(_unitValue,
|
||||
// _unitBase, _areaValue, _depValue)),
|
||||
// ""),
|
||||
// validator: FormBuilderValidators.compose([]),
|
||||
// onChanged: (value) {
|
||||
// setState(() {
|
||||
// _marketValue = double.parse(value!);
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// Text('Amount of Depreciation'),
|
||||
// const SizedBox(height: 5),
|
||||
// Container(
|
||||
// height: 45.0,
|
||||
// width: double.infinity,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// border: Border.all(
|
||||
// color: Colors.grey,
|
||||
// width: 1.0,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(5.0),
|
||||
// ),
|
||||
// child: Align(
|
||||
// alignment: Alignment.center,
|
||||
// child: Text(NumberFormat.currency(
|
||||
// locale: 'en-PH', symbol: "₱")
|
||||
// .format(_amountofDepreciation(_unitValue,
|
||||
// _unitBase, _areaValue, _depValue)))),
|
||||
// ),
|
||||
|
||||
Visibility(
|
||||
visible: !_withoutBUCC,
|
||||
child: Column(
|
||||
|
@ -557,6 +578,8 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
child: FormBuilderTextField(
|
||||
enabled: isSecondHand,
|
||||
name: 'secondHandMat',
|
||||
keyboardType:
|
||||
TextInputType.phone,
|
||||
textAlign: TextAlign.center,
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
|
@ -600,7 +623,6 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
const Text('Market Value'),
|
||||
const SizedBox(height: 5),
|
||||
|
@ -707,7 +729,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -726,7 +748,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
.add(const LoadAdditionalItems());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
@ -735,7 +757,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
)); // Use your actual widget
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
|
|
@ -2,8 +2,12 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:im_stepper/stepper.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:unit2/model/offline/offline_profile.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/building_and_structure.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/drawing_pad.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/flutter_painter.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/imagePicker.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/property_appraisal.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/property_assessment.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/property_owner_info.dart';
|
||||
|
@ -29,7 +33,7 @@ class AddBuilding extends StatefulWidget {
|
|||
|
||||
class _AddBuilding extends State<AddBuilding> {
|
||||
int activeStep = 0; // Initial step set to 5.
|
||||
int upperBound = 6;
|
||||
int upperBound = 7;
|
||||
|
||||
List<String> foundation = [];
|
||||
List<String> column = [];
|
||||
|
@ -39,6 +43,18 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
List<String> flooring = [];
|
||||
List<String> walls = [];
|
||||
|
||||
bool foundationOthers = false;
|
||||
bool columOthers = false;
|
||||
bool beamsOthers = false;
|
||||
bool tfOthers = false;
|
||||
bool roofOthers = false;
|
||||
bool flooringOthers = false;
|
||||
bool wpOthers = false;
|
||||
|
||||
String bldgType = "";
|
||||
String bldgKind = "Structure type";
|
||||
String unitValue = "";
|
||||
|
||||
void PrevBtn() {
|
||||
setState(() {
|
||||
activeStep--;
|
||||
|
@ -93,6 +109,66 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
});
|
||||
}
|
||||
|
||||
void updateFoundationOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
foundationOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateColumOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
columOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateBeamsOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
beamsOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateTfOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
tfOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateRoofOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
roofOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateFlooringOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
flooringOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updateWpOthers(bool updatedOthers) {
|
||||
setState(() {
|
||||
wpOthers = updatedOthers;
|
||||
});
|
||||
}
|
||||
|
||||
void updatedBldgType(dynamic updatedBldgType) {
|
||||
setState(() {
|
||||
bldgType = updatedBldgType;
|
||||
});
|
||||
}
|
||||
|
||||
void updatedBldgKind(dynamic updatedBldgKind) {
|
||||
setState(() {
|
||||
bldgKind = updatedBldgKind;
|
||||
});
|
||||
}
|
||||
|
||||
void updatedUnitValue(dynamic updatedUnitValue) {
|
||||
setState(() {
|
||||
unitValue = updatedUnitValue;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print(widget.offlineProfile.toJson());
|
||||
|
@ -114,7 +190,7 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
),
|
||||
body: Column(children: [
|
||||
NumberStepper(
|
||||
numbers: [1, 2, 3, 4, 5, 6, 7, 8],
|
||||
numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
stepPadding: 5,
|
||||
activeStepColor: primary,
|
||||
numberStyle: TextStyle(color: Colors.white),
|
||||
|
@ -162,16 +238,35 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
|
||||
case 2:
|
||||
return GeneralDescriptionOfflinePage(
|
||||
NextBtn, PrevBtn, widget.offlineProfile);
|
||||
|
||||
NextBtn,
|
||||
PrevBtn,
|
||||
widget.offlineProfile,
|
||||
bldgKind,
|
||||
bldgType,
|
||||
unitValue,
|
||||
updatedUnitValue,
|
||||
updatedBldgKind,
|
||||
updatedBldgType);
|
||||
case 3:
|
||||
return FlutterDraw();
|
||||
|
||||
case 4:
|
||||
return BuildingAndStructureOfflinePage(
|
||||
PrevBtn, NextBtn, widget.offlineProfile);
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
return StatefulBuilder(
|
||||
builder: (context, StateSetter setInnerState) =>
|
||||
StructuralMaterialsOfflinePage(PrevBtn, NextBtn,
|
||||
StructuralMaterialsOfflinePage(
|
||||
PrevBtn,
|
||||
NextBtn,
|
||||
foundationOthers: foundationOthers,
|
||||
columOthers: columOthers,
|
||||
beamsOthers: beamsOthers,
|
||||
tfOthers: tfOthers,
|
||||
roofOthers: roofOthers,
|
||||
flooringOthers: flooringOthers,
|
||||
wpOthers: wpOthers,
|
||||
foundation: foundation,
|
||||
column: column,
|
||||
beam: beam,
|
||||
|
@ -185,17 +280,25 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
updateFlooring: updateFlooring,
|
||||
updateRoof: updateRoof,
|
||||
updateTrussFraming: updateTrussFraming,
|
||||
updateWalls: updateWalls));
|
||||
updateWalls: updateWalls,
|
||||
updateFoundationOthers: updateFoundationOthers,
|
||||
updateColumOthers: updateColumOthers,
|
||||
updateBeamsOthers: updateBeamsOthers,
|
||||
updateTfOthers: updateTfOthers,
|
||||
updateRoofOthers: updateRoofOthers,
|
||||
updateFlooringOthers: updateFlooringOthers,
|
||||
updateWpOthers: updateWpOthers,
|
||||
));
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
return AdditionalItemOfflinePage(
|
||||
PrevBtn, NextBtn, widget.offlineProfile);
|
||||
|
||||
case 6:
|
||||
case 7:
|
||||
return PropertyAppraisalOfflinePage(
|
||||
NextBtn, PrevBtn, widget.offlineProfile);
|
||||
|
||||
case 7:
|
||||
case 8:
|
||||
return PropertyAssessmentOfflinePage(
|
||||
onCloseTransaction, widget.offlineProfile);
|
||||
|
||||
|
@ -204,8 +307,12 @@ class _AddBuilding extends State<AddBuilding> {
|
|||
}
|
||||
}
|
||||
|
||||
void onCloseTransaction() {
|
||||
void onCloseTransaction() async {
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
Navigator.of(context).pop();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
widget.triggerBlocEvent();
|
||||
});
|
||||
await tempID.setBool('floorSketchSaved', false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,463 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_drawing_board/flutter_drawing_board.dart';
|
||||
import 'package:flutter_drawing_board/paint_contents.dart';
|
||||
import 'package:flutter_drawing_board/paint_extension.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:unit2/utils/request_permission.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:unit2/utils/urls.dart'; // Removed 'as http'
|
||||
|
||||
// import 'test_data.dart';
|
||||
|
||||
Future<ui.Image> _getImage(String path) async {
|
||||
final Completer<ImageInfo> completer = Completer<ImageInfo>();
|
||||
final NetworkImage img = NetworkImage(path);
|
||||
img.resolve(ImageConfiguration.empty).addListener(
|
||||
ImageStreamListener((ImageInfo info, _) {
|
||||
completer.complete(info);
|
||||
}),
|
||||
);
|
||||
|
||||
final ImageInfo imageInfo = await completer.future;
|
||||
|
||||
return imageInfo.image;
|
||||
}
|
||||
|
||||
const Map<String, dynamic> _testLine1 = <String, dynamic>{
|
||||
'type': 'StraightLine',
|
||||
'startPoint': <String, dynamic>{
|
||||
'dx': 68.94337550070736,
|
||||
'dy': 62.05980083656557
|
||||
},
|
||||
'endPoint': <String, dynamic>{
|
||||
'dx': 277.1373386828114,
|
||||
'dy': 277.32029957032194
|
||||
},
|
||||
'paint': <String, dynamic>{
|
||||
'blendMode': 3,
|
||||
'color': 4294198070,
|
||||
'filterQuality': 3,
|
||||
'invertColors': false,
|
||||
'isAntiAlias': false,
|
||||
'strokeCap': 1,
|
||||
'strokeJoin': 1,
|
||||
'strokeWidth': 4.0,
|
||||
'style': 1
|
||||
}
|
||||
};
|
||||
|
||||
const Map<String, dynamic> _testLine2 = <String, dynamic>{
|
||||
'type': 'StraightLine',
|
||||
'startPoint': <String, dynamic>{
|
||||
'dx': 106.35164817830423,
|
||||
'dy': 255.9575653134524
|
||||
},
|
||||
'endPoint': <String, dynamic>{
|
||||
'dx': 292.76034659254094,
|
||||
'dy': 92.125586665872
|
||||
},
|
||||
'paint': <String, dynamic>{
|
||||
'blendMode': 3,
|
||||
'color': 4294198070,
|
||||
'filterQuality': 3,
|
||||
'invertColors': false,
|
||||
'isAntiAlias': false,
|
||||
'strokeCap': 1,
|
||||
'strokeJoin': 1,
|
||||
'strokeWidth': 4.0,
|
||||
'style': 1
|
||||
}
|
||||
};
|
||||
|
||||
/// Custom drawn triangles
|
||||
class Triangle extends PaintContent {
|
||||
Triangle();
|
||||
|
||||
Triangle.data({
|
||||
required this.startPoint,
|
||||
required this.A,
|
||||
required this.B,
|
||||
required this.C,
|
||||
required Paint paint,
|
||||
}) : super.paint(paint);
|
||||
|
||||
factory Triangle.fromJson(Map<String, dynamic> data) {
|
||||
return Triangle.data(
|
||||
startPoint: jsonToOffset(data['startPoint'] as Map<String, dynamic>),
|
||||
A: jsonToOffset(data['A'] as Map<String, dynamic>),
|
||||
B: jsonToOffset(data['B'] as Map<String, dynamic>),
|
||||
C: jsonToOffset(data['C'] as Map<String, dynamic>),
|
||||
paint: jsonToPaint(data['paint'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Offset startPoint = Offset.zero;
|
||||
|
||||
Offset A = Offset.zero;
|
||||
Offset B = Offset.zero;
|
||||
Offset C = Offset.zero;
|
||||
|
||||
@override
|
||||
void startDraw(Offset startPoint) => this.startPoint = startPoint;
|
||||
|
||||
@override
|
||||
void drawing(Offset nowPoint) {
|
||||
A = Offset(
|
||||
startPoint.dx + (nowPoint.dx - startPoint.dx) / 2, startPoint.dy);
|
||||
B = Offset(startPoint.dx, nowPoint.dy);
|
||||
C = nowPoint;
|
||||
}
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, Size size, bool deeper) {
|
||||
final Path path = Path()
|
||||
..moveTo(A.dx, A.dy)
|
||||
..lineTo(B.dx, B.dy)
|
||||
..lineTo(C.dx, C.dy)
|
||||
..close();
|
||||
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
|
||||
@override
|
||||
Triangle copy() => Triangle();
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toContentJson() {
|
||||
return <String, dynamic>{
|
||||
'startPoint': startPoint.toJson(),
|
||||
'A': A.toJson(),
|
||||
'B': B.toJson(),
|
||||
'C': C.toJson(),
|
||||
'paint': paint.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom drawn image
|
||||
/// url: https://web-strapi.mrmilu.com/uploads/flutter_logo_470e9f7491.png
|
||||
const String _imageUrl =
|
||||
'https://web-strapi.mrmilu.com/uploads/flutter_logo_470e9f7491.png';
|
||||
|
||||
class ImageContent extends PaintContent {
|
||||
ImageContent(this.image, {this.imageUrl = ''});
|
||||
|
||||
ImageContent.data({
|
||||
required this.startPoint,
|
||||
required this.size,
|
||||
required this.image,
|
||||
required this.imageUrl,
|
||||
required Paint paint,
|
||||
}) : super.paint(paint);
|
||||
|
||||
factory ImageContent.fromJson(Map<String, dynamic> data) {
|
||||
return ImageContent.data(
|
||||
startPoint: jsonToOffset(data['startPoint'] as Map<String, dynamic>),
|
||||
size: jsonToOffset(data['size'] as Map<String, dynamic>),
|
||||
imageUrl: data['imageUrl'] as String,
|
||||
image: data['image'] as ui.Image,
|
||||
paint: jsonToPaint(data['paint'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Offset startPoint = Offset.zero;
|
||||
Offset size = Offset.zero;
|
||||
final String imageUrl;
|
||||
final ui.Image image;
|
||||
|
||||
@override
|
||||
void startDraw(Offset startPoint) => this.startPoint = startPoint;
|
||||
|
||||
@override
|
||||
void drawing(Offset nowPoint) => size = nowPoint - startPoint;
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, Size size, bool deeper) {
|
||||
final Rect rect = Rect.fromPoints(startPoint, startPoint + this.size);
|
||||
paintImage(canvas: canvas, rect: rect, image: image, fit: BoxFit.fill);
|
||||
}
|
||||
|
||||
@override
|
||||
ImageContent copy() => ImageContent(image);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toContentJson() {
|
||||
return <String, dynamic>{
|
||||
'startPoint': startPoint.toJson(),
|
||||
'size': size.toJson(),
|
||||
'imageUrl': imageUrl,
|
||||
'paint': paint.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class DrawingScreen extends StatelessWidget {
|
||||
const DrawingScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Drawing Test',
|
||||
theme: ThemeData(primarySwatch: Colors.blue),
|
||||
home: const MyHomePage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
/// 绘制控制器
|
||||
final DrawingController _drawingController = DrawingController();
|
||||
|
||||
final TransformationController _transformationController =
|
||||
TransformationController();
|
||||
|
||||
final GlobalKey _repaintBoundaryKey = GlobalKey();
|
||||
|
||||
File? _image;
|
||||
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_drawingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 获取画板数据 `getImageData()`
|
||||
Future<void> _getImageData() async {
|
||||
final Uint8List? data =
|
||||
(await _drawingController.getImageData())?.buffer.asUint8List();
|
||||
if (data == null) {
|
||||
debugPrint('获取图片数据失败');
|
||||
return;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext c) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(c), child: Image.memory(data)),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _saveImageToDevice(Uint8List data) async {
|
||||
// Get the temporary directory
|
||||
final directory = await getTemporaryDirectory();
|
||||
final tempDirectory = directory.path;
|
||||
|
||||
// Create a file path in the temporary directory
|
||||
final filePath = '$tempDirectory/181.png';
|
||||
final file = File(filePath);
|
||||
|
||||
// Write the image bytes to the file
|
||||
await file.writeAsBytes(data);
|
||||
|
||||
// Return the file path
|
||||
print(filePath);
|
||||
return filePath;
|
||||
}
|
||||
|
||||
Future<void> _saveAndShowImage() async {
|
||||
final Uint8List? data =
|
||||
(await _drawingController.getImageData())?.buffer.asUint8List();
|
||||
if (data == null) {
|
||||
debugPrint('Failed to get image data');
|
||||
return;
|
||||
}
|
||||
|
||||
final path = await _saveImageToDevice(data);
|
||||
|
||||
if (mounted) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext c) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(c), child: Image.memory(data)),
|
||||
);
|
||||
},
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image saved to $path')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showImage() async {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext c) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.pop(c),
|
||||
child:
|
||||
Image.file(File('/data/user/0/com.app.rpass/cache/img.png'))),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _restBoard() {
|
||||
_transformationController.value = Matrix4.identity();
|
||||
}
|
||||
|
||||
Future<Response> _postBuildingDetails(Map<String, dynamic> details) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
|
||||
// Construct the headers for the request
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret,
|
||||
};
|
||||
|
||||
// Create a MultipartRequest
|
||||
var request = MultipartRequest(
|
||||
'POST',
|
||||
Uri.parse(
|
||||
'https://${Url.instance.host()}/api/rptass_app/bldgappr_sketch/'),
|
||||
);
|
||||
|
||||
// Add the headers to the request
|
||||
request.headers.addAll(headers);
|
||||
|
||||
// Add JSON data as a field
|
||||
// Add individual fields to the request
|
||||
details.forEach((key, value) {
|
||||
request.fields[key] = value.toString();
|
||||
});
|
||||
|
||||
var file = File(imagePath);
|
||||
// Add the floor sketch image file, if it exists
|
||||
|
||||
request.files.add(
|
||||
await MultipartFile.fromPath(
|
||||
'floor_sketch', // Field name in the API
|
||||
file.path,
|
||||
filename: file.path,
|
||||
),
|
||||
);
|
||||
|
||||
// Send the request and get the response
|
||||
var streamedResponse = await request.send();
|
||||
return await Response.fromStream(streamedResponse);
|
||||
}
|
||||
|
||||
Future<void> _uploadImage() async {
|
||||
// Create a map with the required fields
|
||||
var file = File(imagePath);
|
||||
Map<String, dynamic> detailsMap = {
|
||||
"bldgappr_details_id": 182, // int8 NOT NULL
|
||||
"date_created": DateTime.now().toIso8601String(), // timestamptz NULL
|
||||
"floor_sketch": file.path, // text NULL
|
||||
"gen_code": "5TH", // varchar(20) NOT NULL
|
||||
};
|
||||
|
||||
try {
|
||||
Response response = await _postBuildingDetails(detailsMap);
|
||||
print(response.body);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
print('Upload successful');
|
||||
} else {
|
||||
print('Upload failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: Colors.white,
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete_rounded),
|
||||
color: Colors.red,
|
||||
iconSize: 38,
|
||||
tooltip: 'Open shopping cart',
|
||||
onPressed: () {
|
||||
_showImage();
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.check_circle),
|
||||
color: Colors.red,
|
||||
iconSize: 35,
|
||||
tooltip: 'Open shopping cart',
|
||||
onPressed: () {
|
||||
_saveAndShowImage();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return RepaintBoundary(
|
||||
key: _repaintBoundaryKey,
|
||||
child: DrawingBoard(
|
||||
// boardPanEnabled: false,
|
||||
// boardScaleEnabled: false,
|
||||
transformationController: _transformationController,
|
||||
controller: _drawingController,
|
||||
background: Container(
|
||||
width: constraints.maxWidth,
|
||||
height: constraints.maxHeight,
|
||||
color: Colors.grey,
|
||||
),
|
||||
showDefaultActions: true,
|
||||
showDefaultTools: true,
|
||||
|
||||
defaultToolsBuilder: (Type t, _) {
|
||||
return DrawingBoard.defaultTools(t, _drawingController)
|
||||
..insert(
|
||||
1,
|
||||
DefToolItem(
|
||||
icon: Icons.change_history_rounded,
|
||||
isActive: t == Triangle,
|
||||
onTap: () =>
|
||||
_drawingController.setPaintContent(Triangle()),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,818 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:http/http.dart'; // Removed 'as http'
|
||||
import 'package:path/path.dart'; // For basename function
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter_extensions.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter_pure.dart';
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:phosphor_flutter/phosphor_flutter.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:unit2/model/passo/floor_sketch.dart';
|
||||
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
|
||||
import '../../../../../sevices/offline/offline_passo/admin/sql_services/sql_services.dart';
|
||||
|
||||
class FlutterDraw extends StatefulWidget {
|
||||
const FlutterDraw({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FlutterPainterExampleState createState() => _FlutterPainterExampleState();
|
||||
}
|
||||
|
||||
class _FlutterPainterExampleState extends State<FlutterDraw> {
|
||||
static const Color red = Color.fromARGB(255, 0, 0, 0);
|
||||
FocusNode textFocusNode = FocusNode();
|
||||
late PainterController controller;
|
||||
ui.Image? backgroundImage;
|
||||
Paint shapePaint = Paint()
|
||||
..strokeWidth = 5
|
||||
..color = Colors.black
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
File? _image;
|
||||
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
static const List<String> imageLinks = [
|
||||
"https://i.imgur.com/btoI5OX.png",
|
||||
"https://i.imgur.com/EXTQFt7.png",
|
||||
"https://i.imgur.com/EDNjJYL.png",
|
||||
"https://i.imgur.com/uQKD6NL.png",
|
||||
"https://i.imgur.com/cMqVRbl.png",
|
||||
"https://i.imgur.com/1cJBAfI.png",
|
||||
"https://i.imgur.com/eNYfHKL.png",
|
||||
"https://i.imgur.com/c4Ag5yt.png",
|
||||
"https://i.imgur.com/GhpCJuf.png",
|
||||
"https://i.imgur.com/XVMeluF.png",
|
||||
"https://i.imgur.com/mt2yO6Z.png",
|
||||
"https://i.imgur.com/rw9XP1X.png",
|
||||
"https://i.imgur.com/pD7foZ8.png",
|
||||
"https://i.imgur.com/13Y3vp2.png",
|
||||
"https://i.imgur.com/ojv3yw1.png",
|
||||
"https://i.imgur.com/f8ZNJJ7.png",
|
||||
"https://i.imgur.com/BiYkHzw.png",
|
||||
"https://i.imgur.com/snJOcEz.png",
|
||||
"https://i.imgur.com/b61cnhi.png",
|
||||
"https://i.imgur.com/FkDFzYe.png",
|
||||
"https://i.imgur.com/P310x7d.png",
|
||||
"https://i.imgur.com/5AHZpua.png",
|
||||
"https://i.imgur.com/tmvJY4r.png",
|
||||
"https://i.imgur.com/PdVfGkV.png",
|
||||
"https://i.imgur.com/1PRzwBf.png",
|
||||
"https://i.imgur.com/VeeMfBS.png",
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller = PainterController(
|
||||
settings: PainterSettings(
|
||||
text: TextSettings(
|
||||
focusNode: textFocusNode,
|
||||
textStyle: const TextStyle(
|
||||
fontWeight: FontWeight.bold, color: red, fontSize: 18),
|
||||
),
|
||||
freeStyle: const FreeStyleSettings(
|
||||
color: red,
|
||||
strokeWidth: 5,
|
||||
),
|
||||
shape: ShapeSettings(
|
||||
paint: shapePaint,
|
||||
),
|
||||
scale: const ScaleSettings(
|
||||
enabled: true,
|
||||
minScale: 1,
|
||||
maxScale: 5,
|
||||
)));
|
||||
// Listen to focus events of the text field
|
||||
textFocusNode.addListener(onFocus);
|
||||
// Initialize background
|
||||
initBackground();
|
||||
}
|
||||
|
||||
/// Fetches image from an [ImageProvider] (in this example, [NetworkImage])
|
||||
/// to use it as a background
|
||||
void initBackground() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final floorSketchSaved = prefs.getBool('floorSketchSaved') ?? false;
|
||||
final tempID = prefs.getInt('tempid');
|
||||
|
||||
print(floorSketchSaved);
|
||||
|
||||
ui.Image image;
|
||||
|
||||
if (floorSketchSaved && tempID != null) {
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/$tempID.png';
|
||||
image = await _loadImageFromPath(imagePath);
|
||||
} else {
|
||||
image = await const AssetImage('assets/pngs/white_bg.png').image;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
backgroundImage = image;
|
||||
controller.background = image.backgroundDrawable;
|
||||
});
|
||||
}
|
||||
|
||||
/// Updates UI when the focus changes
|
||||
void onFocus() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Future<ui.Image> _loadImageFromPath(String imagePath) async {
|
||||
final file = File(imagePath);
|
||||
final bytes = await file.readAsBytes();
|
||||
final Completer<ui.Image> completer = Completer();
|
||||
ui.decodeImageFromList(bytes, (ui.Image img) {
|
||||
completer.complete(img);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<void> deleteImage(BuildContext context) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final tempID = prefs.getInt('tempid');
|
||||
if (tempID != null) {
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/$tempID.png';
|
||||
final file = File(imagePath);
|
||||
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image deleted successfully')),
|
||||
);
|
||||
|
||||
final image = await const AssetImage('assets/pngs/white_bg.png').image;
|
||||
setState(() {
|
||||
backgroundImage = image;
|
||||
controller.background = image.backgroundDrawable;
|
||||
});
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image does not exist')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildDefault(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size(double.infinity, kToolbarHeight),
|
||||
// Listen to the controller and update the UI when it updates.
|
||||
child: ValueListenableBuilder<PainterControllerValue>(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, child) {
|
||||
return AppBar(
|
||||
title: child,
|
||||
automaticallyImplyLeading: false, // Disable the back button
|
||||
|
||||
actions: [
|
||||
// Delete the selected drawable
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.trash,
|
||||
),
|
||||
onPressed: controller.selectedObjectDrawable == null
|
||||
? null
|
||||
: removeSelectedDrawable,
|
||||
),
|
||||
// Delete the selected drawable
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.flip,
|
||||
),
|
||||
onPressed: controller.selectedObjectDrawable != null &&
|
||||
controller.selectedObjectDrawable is ImageDrawable
|
||||
? flipSelectedImageDrawable
|
||||
: null,
|
||||
),
|
||||
// Redo action
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.arrowClockwise,
|
||||
),
|
||||
onPressed: controller.canRedo ? redo : null,
|
||||
),
|
||||
// Undo action
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.arrowCounterClockwise,
|
||||
),
|
||||
onPressed: controller.canUndo ? undo : null,
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
// Generate image
|
||||
floatingActionButton: Stack(
|
||||
children: <Widget>[
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: FloatingActionButton(
|
||||
heroTag: 'btn1',
|
||||
child: const Icon(
|
||||
PhosphorIcons.imageFill,
|
||||
),
|
||||
onPressed: () => renderAndDisplayImage(context),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 60.0),
|
||||
child: FloatingActionButton(
|
||||
heroTag: 'btn2',
|
||||
child: const Icon(
|
||||
Icons.delete,
|
||||
),
|
||||
onPressed: () => deleteImage(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Add more FloatingActionButton widgets here if needed
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
if (backgroundImage != null)
|
||||
// Enforces constraints
|
||||
Positioned.fill(
|
||||
child: Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio:
|
||||
backgroundImage!.width / backgroundImage!.height,
|
||||
child: FlutterPainter(
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, __) => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.vertical(top: Radius.circular(20)),
|
||||
color: Colors.white54,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (controller.freeStyleMode !=
|
||||
FreeStyleMode.none) ...[
|
||||
const Divider(),
|
||||
const Text("Free Style Settings"),
|
||||
// Control free style stroke width
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Stroke Width")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 2,
|
||||
max: 25,
|
||||
value: controller.freeStyleStrokeWidth,
|
||||
onChanged: setFreeStyleStrokeWidth),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (controller.freeStyleMode ==
|
||||
FreeStyleMode.draw)
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Color")),
|
||||
// Control free style color hue
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
controller.freeStyleColor)
|
||||
.hue,
|
||||
activeColor:
|
||||
controller.freeStyleColor,
|
||||
onChanged: setFreeStyleColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (textFocusNode.hasFocus) ...[
|
||||
const Divider(),
|
||||
const Text("Text settings"),
|
||||
// Control text font size
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Font Size")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 8,
|
||||
max: 96,
|
||||
value:
|
||||
controller.textStyle.fontSize ?? 14,
|
||||
onChanged: setTextFontSize),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Control text color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(flex: 1, child: Text("Color")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
controller.textStyle.color ??
|
||||
red)
|
||||
.hue,
|
||||
activeColor: controller.textStyle.color,
|
||||
onChanged: setTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (controller.shapeFactory != null) ...[
|
||||
const Divider(),
|
||||
const Text("Shape Settings"),
|
||||
|
||||
// Control text color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Stroke Width")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 2,
|
||||
max: 25,
|
||||
value: controller
|
||||
.shapePaint?.strokeWidth ??
|
||||
shapePaint.strokeWidth,
|
||||
onChanged: (value) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
strokeWidth: value,
|
||||
))),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Control shape color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(flex: 1, child: Text("Color")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.color)
|
||||
.hue,
|
||||
activeColor: (controller.shapePaint ??
|
||||
shapePaint)
|
||||
.color,
|
||||
onChanged: (hue) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
color: HSVColor.fromAHSV(
|
||||
1, hue, 1, 1)
|
||||
.toColor(),
|
||||
))),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Fill shape")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Center(
|
||||
child: Switch(
|
||||
value: (controller.shapePaint ??
|
||||
shapePaint)
|
||||
.style ==
|
||||
PaintingStyle.fill,
|
||||
onChanged: (value) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
style: value
|
||||
? PaintingStyle.fill
|
||||
: PaintingStyle.stroke,
|
||||
))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: ValueListenableBuilder(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, __) => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
// Free-style eraser
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.eraser,
|
||||
color: controller.freeStyleMode == FreeStyleMode.erase
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: toggleFreeStyleErase,
|
||||
),
|
||||
// Free-style drawing
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.scribbleLoop,
|
||||
color: controller.freeStyleMode == FreeStyleMode.draw
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: toggleFreeStyleDraw,
|
||||
),
|
||||
// Add text
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.textT,
|
||||
color: textFocusNode.hasFocus
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: addText,
|
||||
),
|
||||
// Add sticker image
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.sticker,
|
||||
),
|
||||
onPressed: () => addSticker(context),
|
||||
),
|
||||
// Add shapes
|
||||
if (controller.shapeFactory == null)
|
||||
PopupMenuButton<ShapeFactory?>(
|
||||
tooltip: "Add shape",
|
||||
itemBuilder: (context) => <ShapeFactory, String>{
|
||||
LineFactory(): "Line",
|
||||
ArrowFactory(): "Arrow",
|
||||
DoubleArrowFactory(): "Double Arrow",
|
||||
RectangleFactory(): "Rectangle",
|
||||
OvalFactory(): "Oval",
|
||||
}
|
||||
.entries
|
||||
.map((e) => PopupMenuItem(
|
||||
value: e.key,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
getShapeIcon(e.key),
|
||||
color: Colors.black,
|
||||
),
|
||||
Text(" ${e.value}")
|
||||
],
|
||||
)))
|
||||
.toList(),
|
||||
onSelected: selectShape,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
getShapeIcon(controller.shapeFactory),
|
||||
color: controller.shapeFactory != null
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
getShapeIcon(controller.shapeFactory),
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () => selectShape(null),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return buildDefault(context);
|
||||
}
|
||||
|
||||
static IconData getShapeIcon(ShapeFactory? shapeFactory) {
|
||||
if (shapeFactory is LineFactory) return PhosphorIcons.lineSegment;
|
||||
if (shapeFactory is ArrowFactory) return PhosphorIcons.arrowUpRight;
|
||||
if (shapeFactory is DoubleArrowFactory) {
|
||||
return PhosphorIcons.arrowsHorizontal;
|
||||
}
|
||||
if (shapeFactory is RectangleFactory) return PhosphorIcons.rectangle;
|
||||
if (shapeFactory is OvalFactory) return PhosphorIcons.circle;
|
||||
return PhosphorIcons.polygon;
|
||||
}
|
||||
|
||||
void undo() {
|
||||
controller.undo();
|
||||
}
|
||||
|
||||
void redo() {
|
||||
controller.redo();
|
||||
}
|
||||
|
||||
void toggleFreeStyleDraw() {
|
||||
controller.freeStyleMode = controller.freeStyleMode != FreeStyleMode.draw
|
||||
? FreeStyleMode.draw
|
||||
: FreeStyleMode.none;
|
||||
}
|
||||
|
||||
void toggleFreeStyleErase() {
|
||||
controller.freeStyleMode = controller.freeStyleMode != FreeStyleMode.erase
|
||||
? FreeStyleMode.erase
|
||||
: FreeStyleMode.none;
|
||||
}
|
||||
|
||||
void addText() {
|
||||
if (controller.freeStyleMode != FreeStyleMode.none) {
|
||||
controller.freeStyleMode = FreeStyleMode.none;
|
||||
}
|
||||
controller.addText();
|
||||
}
|
||||
|
||||
void addSticker(BuildContext context) async {
|
||||
final imageLink = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => const SelectStickerImageDialog(
|
||||
imagesLinks: imageLinks,
|
||||
));
|
||||
if (imageLink == null) return;
|
||||
controller.addImage(
|
||||
await NetworkImage(imageLink).image, const Size(100, 100));
|
||||
}
|
||||
|
||||
void setFreeStyleStrokeWidth(double value) {
|
||||
controller.freeStyleStrokeWidth = value;
|
||||
}
|
||||
|
||||
void setFreeStyleColor(double hue) {
|
||||
controller.freeStyleColor = HSVColor.fromAHSV(1, hue, 1, 1).toColor();
|
||||
}
|
||||
|
||||
void setTextFontSize(double size) {
|
||||
// Set state is just to update the current UI, the [FlutterPainter] UI updates without it
|
||||
setState(() {
|
||||
controller.textSettings = controller.textSettings.copyWith(
|
||||
textStyle:
|
||||
controller.textSettings.textStyle.copyWith(fontSize: size));
|
||||
});
|
||||
}
|
||||
|
||||
void setShapeFactoryPaint(Paint paint) {
|
||||
// Set state is just to update the current UI, the [FlutterPainter] UI updates without it
|
||||
setState(() {
|
||||
controller.shapePaint = paint;
|
||||
});
|
||||
}
|
||||
|
||||
void setTextColor(double hue) {
|
||||
controller.textStyle = controller.textStyle
|
||||
.copyWith(color: HSVColor.fromAHSV(1, hue, 1, 1).toColor());
|
||||
}
|
||||
|
||||
void selectShape(ShapeFactory? factory) {
|
||||
controller.shapeFactory = factory;
|
||||
}
|
||||
|
||||
Future<void> _uploadImage() async {
|
||||
// Create a map with the required fields
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
final tempIDS = tempID.getInt('tempid');
|
||||
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/$tempIDS.png';
|
||||
|
||||
await tempID.setBool('floorSketchSaved', true);
|
||||
var file = File(imagePath);
|
||||
// Map<String, dynamic> detailsMap = {
|
||||
// "bldgappr_details_id": 182, // int8 NOT NULL
|
||||
// "date_created": DateTime.now().toIso8601String(), // timestamptz NULL
|
||||
// "floor_sketch": file.path, // text NULL
|
||||
// "gen_code": "5TH", // varchar(20) NOT NULL
|
||||
// };
|
||||
|
||||
var floorSketchs = FloorSketch(
|
||||
bldgapprDetailsId: tempIDS,
|
||||
dateCreated: DateTime.now().toIso8601String(),
|
||||
floorSketch: file.path,
|
||||
genCode: "5TH");
|
||||
|
||||
try {
|
||||
// Response response = await _postBuildingDetails(detailsMap);
|
||||
// print(response.body);
|
||||
await SQLServices.instance.createFloorSketch(floorSketchs);
|
||||
// if (response.statusCode == 201) {
|
||||
// print('Upload successful');
|
||||
// } else {
|
||||
// print('Upload failed with status: ${response.statusCode}');
|
||||
// }
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderAndDisplayImage(BuildContext context) async {
|
||||
if (backgroundImage == null) return;
|
||||
|
||||
final backgroundImageSize = Size(
|
||||
backgroundImage!.width.toDouble(),
|
||||
backgroundImage!.height.toDouble(),
|
||||
);
|
||||
|
||||
try {
|
||||
// Render the image
|
||||
final image = await controller.renderImage(backgroundImageSize);
|
||||
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
final imageBytes = byteData!.buffer.asUint8List();
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
final tempIDS = tempID.getInt('tempid');
|
||||
|
||||
// Write the PNG image data to a file
|
||||
final file = File('${(await getTemporaryDirectory()).path}/$tempIDS.png');
|
||||
await file.writeAsBytes(imageBytes);
|
||||
|
||||
// Show a dialog with the image
|
||||
// ignore: use_build_context_synchronously
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text('Rendered Image'),
|
||||
content: Image.memory(imageBytes),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('SAVE'),
|
||||
onPressed: () {
|
||||
_uploadImage();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('Close'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// Show a snackbar with the file path
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image saved to ${file.path}')),
|
||||
);
|
||||
} catch (e) {
|
||||
// Handle potential errors
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Error: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void removeSelectedDrawable() {
|
||||
final selectedDrawable = controller.selectedObjectDrawable;
|
||||
if (selectedDrawable != null) controller.removeDrawable(selectedDrawable);
|
||||
}
|
||||
|
||||
void flipSelectedImageDrawable() {
|
||||
final imageDrawable = controller.selectedObjectDrawable;
|
||||
if (imageDrawable is! ImageDrawable) return;
|
||||
|
||||
controller.replaceDrawable(
|
||||
imageDrawable, imageDrawable.copyWith(flipped: !imageDrawable.flipped));
|
||||
}
|
||||
}
|
||||
|
||||
class RenderedImageDialog extends StatelessWidget {
|
||||
final Future<Uint8List?> imageFuture;
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
const RenderedImageDialog({Key? key, required this.imageFuture})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Rendered Image"),
|
||||
content: FutureBuilder<Uint8List?>(
|
||||
future: imageFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const SizedBox(
|
||||
height: 50,
|
||||
child: Center(child: CircularProgressIndicator.adaptive()),
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData || snapshot.data == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
return InteractiveViewer(
|
||||
maxScale: 10, child: Image.memory(snapshot.data!));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SelectStickerImageDialog extends StatelessWidget {
|
||||
final List<String> imagesLinks;
|
||||
|
||||
const SelectStickerImageDialog({Key? key, this.imagesLinks = const []})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Select sticker"),
|
||||
content: imagesLinks.isEmpty
|
||||
? const Text("No images")
|
||||
: FractionallySizedBox(
|
||||
heightFactor: 0.5,
|
||||
child: SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
for (final imageLink in imagesLinks)
|
||||
InkWell(
|
||||
onTap: () => Navigator.pop(context, imageLink),
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: 1 / 4,
|
||||
child: Image.network(imageLink),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text("Cancel"),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
@ -23,8 +24,24 @@ class GeneralDescriptionOfflinePage extends StatefulWidget {
|
|||
final VoidCallback gendescPrevBtn;
|
||||
final OfflineProfile offlineProfile;
|
||||
|
||||
final String bldgKind;
|
||||
final String bldgType;
|
||||
final String unitValue;
|
||||
|
||||
final Function(String) updatedUnitValue;
|
||||
final Function(String) updatedBldgKind;
|
||||
final Function(String) updatedBldgType;
|
||||
|
||||
GeneralDescriptionOfflinePage(
|
||||
this.onPutGeneralDescription, this.gendescPrevBtn, this.offlineProfile);
|
||||
this.onPutGeneralDescription,
|
||||
this.gendescPrevBtn,
|
||||
this.offlineProfile,
|
||||
this.bldgKind,
|
||||
this.bldgType,
|
||||
this.unitValue,
|
||||
this.updatedUnitValue,
|
||||
this.updatedBldgKind,
|
||||
this.updatedBldgType);
|
||||
|
||||
@override
|
||||
_GeneralDescriptionOfflinePage createState() =>
|
||||
|
@ -51,10 +68,6 @@ class _GeneralDescriptionOfflinePage
|
|||
: now = DateTime.now(),
|
||||
formatter = DateFormat.yMMMMd('en_US').format(DateTime.now());
|
||||
|
||||
late String bldgType;
|
||||
late String bldgKind;
|
||||
late String unitValue;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocConsumer<UnitConstructionAdminBloc, UnitConstructionAdminState>(
|
||||
|
@ -99,23 +112,31 @@ class _GeneralDescriptionOfflinePage
|
|||
errorText: "This field is required"),
|
||||
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Structure Type", "").copyWith(
|
||||
normalTextFieldStyle(widget.bldgKind, "").copyWith(
|
||||
suffixIcon: const Icon(Icons.arrow_drop_down)),
|
||||
////agency suggestion tap
|
||||
focusNode: focus,
|
||||
suggestionState: Suggestion.expand,
|
||||
onSuggestionTap: (unit) {
|
||||
onSuggestionTap: (unit) async {
|
||||
setState(() {
|
||||
bldgKind =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
bldgType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
|
||||
unitValue = unit.item!.unitValue;
|
||||
widget.updatedBldgKind(
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}');
|
||||
widget.updatedBldgType(
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}');
|
||||
widget.updatedUnitValue(unit.item!.unitValue);
|
||||
|
||||
offlineBldgKey.currentState!
|
||||
.patchValue({'bldg_type': unit.item});
|
||||
});
|
||||
|
||||
// Save the selected UnitConstruct to SharedPreferences
|
||||
SharedPreferences prefs =
|
||||
await SharedPreferences.getInstance();
|
||||
String jsonString = jsonEncode(unit.item!.toJson());
|
||||
await prefs.setString(
|
||||
'selected_bldg_type', jsonString);
|
||||
|
||||
// Unfocus the current focus node
|
||||
focus.unfocus();
|
||||
},
|
||||
),
|
||||
|
@ -128,8 +149,8 @@ class _GeneralDescriptionOfflinePage
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Bldg. Permit No.", "", 'bldg_permit'),
|
||||
child: customTextField("Bldg. Permit No.", "",
|
||||
'bldg_permit', TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -187,45 +208,47 @@ class _GeneralDescriptionOfflinePage
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Bldg. Age", "", 'bldg_age'),
|
||||
child: customTextField("Bldg. Age", "", 'bldg_age',
|
||||
TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. of storeys", "", 'no_of_storeys'))
|
||||
child: customTextField("No. of storeys", "",
|
||||
'no_of_storeys', TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 1st Floor", "", 'area_of_1stFl'),
|
||||
child: customTextField("Area of 1st Floor", "",
|
||||
'area_of_1stFl', TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 2nd Floor", "", 'area_of_2ndFl'))
|
||||
child: customTextField("Area of 2nd Floor", "",
|
||||
'area_of_2ndFl', TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 3rd Floor", "", 'area_of_3rdFl')),
|
||||
child: customTextField("Area of 3rd Floor", "",
|
||||
'area_of_3rdFl', TextInputType.number)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 4th Floor", "", 'area_of_4thFl'))
|
||||
child: customTextField("Area of 4th Floor", "",
|
||||
'area_of_4thFl', TextInputType.number))
|
||||
]),
|
||||
customTextField("Total Area", "", 'total_area'),
|
||||
customTextField(
|
||||
"Total Area", "", 'total_area', TextInputType.number),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
|
@ -259,8 +282,8 @@ class _GeneralDescriptionOfflinePage
|
|||
widget.offlineProfile.firstName!,
|
||||
dateCreated: formatter,
|
||||
dateModified: 'None',
|
||||
bldgKind: bldgKind ?? "",
|
||||
strucType: bldgType ?? "",
|
||||
bldgKind: widget.bldgKind ?? "",
|
||||
strucType: widget.bldgType ?? "",
|
||||
bldgPermit:
|
||||
offlineBldgKey.currentState?.value['bldg_permit'] ??
|
||||
" ",
|
||||
|
@ -288,7 +311,7 @@ class _GeneralDescriptionOfflinePage
|
|||
totalFloorArea: offlineBldgKey.currentState?.value['total_area'] ?? "0",
|
||||
floorSketch: null,
|
||||
actualUse: offlineBldgKey.currentState?.value['actual_use'] ?? "",
|
||||
unitValue: unitValue ?? "",
|
||||
unitValue: widget.unitValue ?? "",
|
||||
genCode: '5th'));
|
||||
widget.onPutGeneralDescription();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:http/http.dart'; // Removed 'as http'
|
||||
import 'package:path/path.dart'; // For basename function
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:unit2/model/location/purok.dart';
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
|
||||
class ImagePickerScreen extends StatefulWidget {
|
||||
@override
|
||||
_ImagePickerScreenState createState() => _ImagePickerScreenState();
|
||||
}
|
||||
|
||||
class _ImagePickerScreenState extends State<ImagePickerScreen> {
|
||||
File? _image;
|
||||
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
Future<void> _pickImage() async {
|
||||
final pickedFile =
|
||||
await ImagePicker().pickImage(source: ImageSource.gallery);
|
||||
|
||||
setState(() {
|
||||
if (pickedFile != null) {
|
||||
_image = File(pickedFile.path);
|
||||
} else {
|
||||
print('No image selected.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<Response> _postBuildingDetails(Map<String, dynamic> details) async {
|
||||
String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z";
|
||||
String xClientKeySecret = "unitcYqAN7GGalyz";
|
||||
|
||||
// Construct the headers for the request
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret,
|
||||
};
|
||||
|
||||
// Create a MultipartRequest
|
||||
var request = MultipartRequest(
|
||||
'POST',
|
||||
Uri.parse(
|
||||
'https://${Url.instance.host()}/api/rptass_app/bldgappr_sketch/'),
|
||||
);
|
||||
|
||||
// Add the headers to the request
|
||||
request.headers.addAll(headers);
|
||||
|
||||
// Add JSON data as a field
|
||||
// Add individual fields to the request
|
||||
details.forEach((key, value) {
|
||||
request.fields[key] = value.toString();
|
||||
});
|
||||
|
||||
var file = File(imagePath);
|
||||
// Add the floor sketch image file, if it exists
|
||||
|
||||
var fileName = basename(file.path);
|
||||
request.files.add(
|
||||
await MultipartFile.fromPath(
|
||||
'floor_sketch', // Field name in the API
|
||||
file.path,
|
||||
filename: fileName,
|
||||
),
|
||||
);
|
||||
|
||||
// Send the request and get the response
|
||||
var streamedResponse = await request.send();
|
||||
return await Response.fromStream(streamedResponse);
|
||||
}
|
||||
|
||||
Future<void> _uploadImage() async {
|
||||
// Create a map with the required fields
|
||||
var file = File(imagePath);
|
||||
Map<String, dynamic> detailsMap = {
|
||||
"bldgappr_details_id": 182, // int8 NOT NULL
|
||||
"date_created": DateTime.now().toIso8601String(), // timestamptz NULL
|
||||
"floor_sketch": file.path, // text NULL
|
||||
"gen_code": "5TH", // varchar(20) NOT NULL
|
||||
};
|
||||
|
||||
try {
|
||||
Response response = await _postBuildingDetails(detailsMap);
|
||||
print(response.body);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
print('Upload successful');
|
||||
} else {
|
||||
print('Upload failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Pick and Upload Image'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
_image == null ? Text('No image selected.') : Image.file(_image!),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _pickImage,
|
||||
child: Text('Pick Image'),
|
||||
// return "192.168.10.221:3004";
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _uploadImage,
|
||||
child: Text('Upload Image'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ class LandRefLocationOfflinePage extends StatefulWidget {
|
|||
class _LandRefLocationOfflinePage extends State<LandRefLocationOfflinePage> {
|
||||
final DateTime now;
|
||||
final String formatter;
|
||||
bool sameOwner = false;
|
||||
|
||||
_LandRefLocationOfflinePage()
|
||||
: now = DateTime.now(),
|
||||
|
@ -126,8 +127,8 @@ class _LandRefLocationOfflinePage extends State<LandRefLocationOfflinePage> {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. / Street", "", 'street'),
|
||||
child: customTextField("No. / Street", "",
|
||||
'street', TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -144,49 +145,92 @@ class _LandRefLocationOfflinePage extends State<LandRefLocationOfflinePage> {
|
|||
fontWeight: FontWeight.bold, fontSize: 18),
|
||||
textAlign: TextAlign.left),
|
||||
),
|
||||
customTextField("Land Owner", "", 'l_owner'),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 50, // Adjust the width as needed
|
||||
height: 50, // Adjust the height as needed
|
||||
child: Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: sameOwner,
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
sameOwner = value!;
|
||||
offlineBldgKey.currentState!
|
||||
.patchValue({
|
||||
'l_owner': offlineBldgKey.currentState
|
||||
?.value['fname'] +
|
||||
' ' +
|
||||
offlineBldgKey.currentState
|
||||
?.value['mname'] +
|
||||
' ' +
|
||||
offlineBldgKey
|
||||
.currentState?.value['lname']
|
||||
});
|
||||
offlineBldgKey.currentState!
|
||||
.patchValue({
|
||||
'l_td_arp': offlineBldgKey
|
||||
.currentState?.value['arp_td']
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
Text('Same building owner')
|
||||
],
|
||||
),
|
||||
// Other widgets in the column
|
||||
],
|
||||
),
|
||||
customTextField(
|
||||
"Land Owner", "", 'l_owner', TextInputType.text),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"OCT/TCT/CLOA No.", "", 'oct_tct_cloa'),
|
||||
child: customTextField("OCT/TCT/CLOA No.", "",
|
||||
'oct_tct_cloa', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Survey No.", "", 'survey_no'))
|
||||
child: customTextField("Survey No.", "",
|
||||
'survey_no', TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Lot No.", "", 'lot_no'),
|
||||
child: customTextField("Lot No.", "", 'lot_no',
|
||||
TextInputType.streetAddress),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child:
|
||||
customTextField("Blk No.", "", 'blk_no'))
|
||||
child: customTextField("Blk No.", "",
|
||||
'blk_no', TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"TD / ARP No.", "", 'l_td_arp'),
|
||||
child: customTextField("TD / ARP No.", "",
|
||||
'l_td_arp', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Area", "", 'area'))
|
||||
child: customTextField(
|
||||
"Area", "", 'area', TextInputType.phone))
|
||||
]),
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
|
|
|
@ -526,8 +526,8 @@ class _PropertyAssessmentOfflinePage
|
|||
},
|
||||
builder: (context, state) {
|
||||
if (state is BuildingAndStructureLoaded) {
|
||||
return Scaffold(
|
||||
body: ListView(children: [
|
||||
return Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Container(
|
||||
|
@ -544,11 +544,10 @@ class _PropertyAssessmentOfflinePage
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 20), // Adjust margins here
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 20.0, right: 20.0),
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
|
@ -593,19 +592,22 @@ class _PropertyAssessmentOfflinePage
|
|||
const Text(
|
||||
'EFFECTIVITY OF ASSESSMENT / REASSESSMENT / SWORN STATEMENT:',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
fontWeight:
|
||||
FontWeight.bold),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
MainAxisAlignment
|
||||
.spaceAround,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: width / 3 - 20,
|
||||
height: 50,
|
||||
child: customDropDownField(
|
||||
child:
|
||||
customDropDownField(
|
||||
'Qtr',
|
||||
'',
|
||||
'qtr',
|
||||
|
@ -616,51 +618,60 @@ class _PropertyAssessmentOfflinePage
|
|||
child: customTextField(
|
||||
'Sworn Statement No.',
|
||||
'',
|
||||
'sworn_statement')),
|
||||
'sworn_statement',
|
||||
TextInputType
|
||||
.number)),
|
||||
SizedBox(
|
||||
width: width / 3 - 20,
|
||||
height: 50,
|
||||
child: customTextField(
|
||||
'Year', '', 'yr')),
|
||||
'Year',
|
||||
'',
|
||||
'yr',
|
||||
TextInputType
|
||||
.number)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
height: 10,
|
||||
),
|
||||
const Divider(
|
||||
thickness: 2,
|
||||
),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Expanded(
|
||||
child: Row(
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
width: width / 2 - 100,
|
||||
height: 50,
|
||||
child: customDatTimePicker(
|
||||
'Date Received',
|
||||
'',
|
||||
'date_received')),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
'date_received',
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
width: width / 2 - 100,
|
||||
height: 50,
|
||||
child: customDatTimePicker(
|
||||
'Date of Entry',
|
||||
'',
|
||||
'date_of_entry'))
|
||||
'date_of_entry',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
|
@ -685,11 +696,11 @@ class _PropertyAssessmentOfflinePage
|
|||
children: [
|
||||
const Text('Name'),
|
||||
Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
padding:
|
||||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin:
|
||||
const EdgeInsets.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -712,7 +723,8 @@ class _PropertyAssessmentOfflinePage
|
|||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname}',
|
||||
item:
|
||||
signatories,
|
||||
child: ListTile(
|
||||
child:
|
||||
ListTile(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
|
@ -725,14 +737,16 @@ class _PropertyAssessmentOfflinePage
|
|||
)))
|
||||
.toList(),
|
||||
|
||||
validator: FormBuilderValidators
|
||||
validator:
|
||||
FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
searchStyle: TextStyle(),
|
||||
|
||||
////agency suggestion tap
|
||||
focusNode: appraisedByFocus,
|
||||
focusNode:
|
||||
appraisedByFocus,
|
||||
suggestionState:
|
||||
Suggestion.expand,
|
||||
onSuggestionTap:
|
||||
|
@ -764,7 +778,8 @@ class _PropertyAssessmentOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
10, 15, 10, 10),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
|
@ -798,13 +813,15 @@ class _PropertyAssessmentOfflinePage
|
|||
Text('Date'),
|
||||
Container(
|
||||
width: 100,
|
||||
child: customDatTimePicker(
|
||||
'', '', 'app_date')),
|
||||
child:
|
||||
customDatTimePicker(
|
||||
'',
|
||||
'',
|
||||
'app_date')),
|
||||
],
|
||||
),
|
||||
]),
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
|
@ -813,7 +830,8 @@ class _PropertyAssessmentOfflinePage
|
|||
child: Text(
|
||||
'RECOMMENDING APPROVAL:',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
fontWeight:
|
||||
FontWeight.bold),
|
||||
)),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
|
@ -827,11 +845,11 @@ class _PropertyAssessmentOfflinePage
|
|||
children: [
|
||||
const Text('Name'),
|
||||
Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
padding:
|
||||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin:
|
||||
const EdgeInsets.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -854,7 +872,8 @@ class _PropertyAssessmentOfflinePage
|
|||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname}',
|
||||
item:
|
||||
signatories,
|
||||
child: ListTile(
|
||||
child:
|
||||
ListTile(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
|
@ -867,7 +886,8 @@ class _PropertyAssessmentOfflinePage
|
|||
)))
|
||||
.toList(),
|
||||
|
||||
validator: FormBuilderValidators
|
||||
validator:
|
||||
FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
|
@ -905,7 +925,8 @@ class _PropertyAssessmentOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
10, 15, 10, 10),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
|
@ -939,13 +960,15 @@ class _PropertyAssessmentOfflinePage
|
|||
Text('Date'),
|
||||
Container(
|
||||
width: 100,
|
||||
child: customDatTimePicker(
|
||||
'', '', 'rec_date')),
|
||||
child:
|
||||
customDatTimePicker(
|
||||
'',
|
||||
'',
|
||||
'rec_date')),
|
||||
],
|
||||
),
|
||||
]),
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
|
@ -969,11 +992,11 @@ class _PropertyAssessmentOfflinePage
|
|||
children: [
|
||||
const Text('Name'),
|
||||
Container(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
padding:
|
||||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin:
|
||||
const EdgeInsets.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -996,7 +1019,8 @@ class _PropertyAssessmentOfflinePage
|
|||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname}',
|
||||
item:
|
||||
signatories,
|
||||
child: ListTile(
|
||||
child:
|
||||
ListTile(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
|
@ -1009,7 +1033,8 @@ class _PropertyAssessmentOfflinePage
|
|||
)))
|
||||
.toList(),
|
||||
|
||||
validator: FormBuilderValidators
|
||||
validator:
|
||||
FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
|
@ -1047,7 +1072,8 @@ class _PropertyAssessmentOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
10, 15, 10, 10),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
|
@ -1078,7 +1104,8 @@ class _PropertyAssessmentOfflinePage
|
|||
Text('Date'),
|
||||
Container(
|
||||
width: 100,
|
||||
child: customDatTimePicker(
|
||||
child:
|
||||
customDatTimePicker(
|
||||
'',
|
||||
'',
|
||||
'approve_date')),
|
||||
|
@ -1086,7 +1113,6 @@ class _PropertyAssessmentOfflinePage
|
|||
),
|
||||
]),
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
|
@ -1108,7 +1134,8 @@ class _PropertyAssessmentOfflinePage
|
|||
itemHeight: 200,
|
||||
controller: memorandaController,
|
||||
suggestions: memoranda
|
||||
.map((Memoranda memoranda) =>
|
||||
.map(
|
||||
(Memoranda memoranda) =>
|
||||
SearchFieldListItem(
|
||||
'${memoranda.memoranda}',
|
||||
item:
|
||||
|
@ -1157,7 +1184,8 @@ class _PropertyAssessmentOfflinePage
|
|||
onSuggestionTap: (memoranda) {
|
||||
setState(() {
|
||||
_memoranda =
|
||||
memorandaController.text;
|
||||
memorandaController
|
||||
.text;
|
||||
});
|
||||
focuss.unfocus();
|
||||
},
|
||||
|
@ -1168,7 +1196,8 @@ class _PropertyAssessmentOfflinePage
|
|||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: memorandaController,
|
||||
controller:
|
||||
memorandaController,
|
||||
keyboardType:
|
||||
TextInputType.multiline,
|
||||
maxLines: 7,
|
||||
|
@ -1258,7 +1287,8 @@ class _PropertyAssessmentOfflinePage
|
|||
SuggestionDirection.up,
|
||||
onSuggestionTap: (memoranda) {
|
||||
setState(() {
|
||||
_notes = noteController.text;
|
||||
_notes =
|
||||
noteController.text;
|
||||
});
|
||||
focus.unfocus();
|
||||
},
|
||||
|
@ -1307,44 +1337,6 @@ class _PropertyAssessmentOfflinePage
|
|||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
// Container(
|
||||
// alignment: Alignment.center,
|
||||
// padding: EdgeInsets.all(10),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// TextField(
|
||||
// enabled: false,
|
||||
// keyboardType: TextInputType.multiline,
|
||||
// maxLines: 5,
|
||||
// decoration: InputDecoration(
|
||||
// hintText: "Note",
|
||||
// focusedBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(
|
||||
// width: 1,
|
||||
// color: Colors.redAccent)),
|
||||
// disabledBorder: OutlineInputBorder(
|
||||
// borderSide: const BorderSide(
|
||||
// width: 1,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
// enabledBorder: OutlineInputBorder(
|
||||
// borderSide: const BorderSide(
|
||||
// color: Colors.grey,
|
||||
// width: 1,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
|
@ -1353,7 +1345,8 @@ class _PropertyAssessmentOfflinePage
|
|||
final tempID =
|
||||
await SharedPreferences
|
||||
.getInstance();
|
||||
print(tempID.getInt('tempid')! - 1);
|
||||
print(
|
||||
tempID.getInt('tempid')! - 1);
|
||||
// final List<PropertyAssessment>
|
||||
// propertyAssessments = [];
|
||||
DateTime? appDate = offlineBldgKey
|
||||
|
@ -1368,8 +1361,8 @@ class _PropertyAssessmentOfflinePage
|
|||
DateTime? dateReceived =
|
||||
offlineBldgKey.currentState!
|
||||
.value['date_received'];
|
||||
DateTime? entryDate = offlineBldgKey
|
||||
.currentState!
|
||||
DateTime? entryDate =
|
||||
offlineBldgKey.currentState!
|
||||
.value['date_of_entry'];
|
||||
String appDateString =
|
||||
appDate != null
|
||||
|
@ -1404,18 +1397,19 @@ class _PropertyAssessmentOfflinePage
|
|||
.firstName!,
|
||||
dateCreated: '',
|
||||
dateModified: '',
|
||||
actualUse: offlineBldgKey
|
||||
.currentState!
|
||||
.value[
|
||||
'actual_use'] ??
|
||||
actualUse: offlineBldgKey.currentState!.value['actual_use'] ??
|
||||
'', // Replace null with an empty string
|
||||
marketValue:
|
||||
_calculateMarketValue(addItem, state.bldgAndStructure)
|
||||
.toString(),
|
||||
assessmentLevel: assessmentLevel(
|
||||
_calculateMarketValue(
|
||||
addItem, state.bldgAndStructure),
|
||||
offlineBldgKey.currentState?.value['actual_use']),
|
||||
addItem,
|
||||
state
|
||||
.bldgAndStructure),
|
||||
offlineBldgKey
|
||||
.currentState
|
||||
?.value['actual_use']),
|
||||
assessedValue: assessmentValue(_calculateMarketValue(addItem, state.bldgAndStructure), offlineBldgKey.currentState?.value['actual_use']).toString(),
|
||||
taxable: isTaxable == true ? '1' : '0',
|
||||
exempt: isExempt == true ? '1' : '0',
|
||||
|
@ -1429,7 +1423,7 @@ class _PropertyAssessmentOfflinePage
|
|||
approvedbyDate: approveDateString,
|
||||
memoranda: _memoranda,
|
||||
note: _notes,
|
||||
swornstatementNo: offlineBldgKey.currentState!.value['sworn_statement'] ?? '', // Replace null with an empty string
|
||||
swornstatementNo: offlineBldgKey.currentState!.value['sworn_statement'] ?? " ", // Replace null with an empty string
|
||||
dateReceived: receivedDateString,
|
||||
// Replace null with current date
|
||||
entryDateAssessment: entryDateString,
|
||||
|
@ -1449,8 +1443,7 @@ class _PropertyAssessmentOfflinePage
|
|||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primary,
|
||||
foregroundColor: Colors.red),
|
||||
child: const Expanded(
|
||||
child: Padding(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(15.0),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
|
@ -1464,14 +1457,13 @@ class _PropertyAssessmentOfflinePage
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
]));
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
|
|
@ -23,6 +23,7 @@ class _PropertyInfoPage extends State<PropertyInfoOfflinePage> {
|
|||
final transaction_codes = ['New', 'Revision'];
|
||||
final DateTime now;
|
||||
final String formatter;
|
||||
bool isOptional = false;
|
||||
|
||||
_PropertyInfoPage()
|
||||
: now = DateTime.now(),
|
||||
|
@ -52,12 +53,14 @@ class _PropertyInfoPage extends State<PropertyInfoOfflinePage> {
|
|||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("ARP No. / TD No.", "", 'arp_td')),
|
||||
child: customTextField("ARP No. / TD No.", "", 'arp_td',
|
||||
TextInputType.phone)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Pin", "", 'pin')),
|
||||
child: customTextField(
|
||||
"Pin", "", 'pin', TextInputType.phone)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
@ -65,65 +68,111 @@ class _PropertyInfoPage extends State<PropertyInfoOfflinePage> {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("First Name", "", 'fname'),
|
||||
child: customTextField(
|
||||
"First Name", "", 'fname', TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Middle Name", "", 'mname'),
|
||||
child: customTextField(
|
||||
"Middle Name", "", 'mname', TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Last Name", "", 'lname'),
|
||||
child: customTextField(
|
||||
"Last Name", "", 'lname', TextInputType.text),
|
||||
)
|
||||
]),
|
||||
customDatTimePicker("Birthday", "", "bday"),
|
||||
customTextField("Address", "", 'address'),
|
||||
customTextField("Address", "", 'address', TextInputType.text),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "", 'tel_no'),
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 50, // Adjust the width as needed
|
||||
height: 50, // Adjust the height as needed
|
||||
child: Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: isOptional,
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
isOptional = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", 'tin'))
|
||||
]),
|
||||
),
|
||||
Text('Show optional information')
|
||||
],
|
||||
),
|
||||
// Other widgets in the column
|
||||
],
|
||||
),
|
||||
Visibility(
|
||||
visible: isOptional,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Administrator / Benificial User", "", 'benificiary'),
|
||||
"Tel No.", "", 'tel_no', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", 'benificiary_tin'))
|
||||
]),
|
||||
child: customTextField(
|
||||
"TIN", "", 'tin', TextInputType.phone),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child:
|
||||
customTextField("Address", "", 'benificiary_address'),
|
||||
child: customTextField(
|
||||
"Administrator / Beneficial User",
|
||||
"",
|
||||
'benificiary',
|
||||
TextInputType.text,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child:
|
||||
customTextField("Tel No.", "", 'benificiary_telno'))
|
||||
]),
|
||||
child: customTextField("TIN", "", 'benificiary_tin',
|
||||
TextInputType.phone),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Address", "",
|
||||
'benificiary_address', TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "",
|
||||
'benificiary_telno', TextInputType.phone),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
CustomButton(
|
||||
icon: const Icon(Icons.chevron_right, color: Colors.white),
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:signature/signature.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/utils.dart';
|
||||
|
||||
class SignatureDraw extends StatefulWidget {
|
||||
const SignatureDraw({super.key});
|
||||
|
||||
@override
|
||||
State<SignatureDraw> createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<SignatureDraw> {
|
||||
// initialize the signature controller
|
||||
final SignatureController _controller = SignatureController(
|
||||
penStrokeWidth: 1,
|
||||
penColor: Colors.red,
|
||||
exportBackgroundColor: Colors.transparent,
|
||||
exportPenColor: Colors.black,
|
||||
onDrawStart: () => log('onDrawStart called!'),
|
||||
onDrawEnd: () => log('onDrawEnd called!'),
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller
|
||||
..addListener(() => log('Value changed'))
|
||||
..onDrawEnd = () => setState(
|
||||
() {
|
||||
// setState for build to update value of "empty label" in gui
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// IMPORTANT to dispose of the controller
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> exportImage(BuildContext context) async {
|
||||
if (_controller.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
key: Key('snackbarPNG'),
|
||||
content: Text('No content'),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final Uint8List? data =
|
||||
await _controller.toPngBytes(height: 1000, width: 1000);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
await push(
|
||||
context,
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('PNG Image'),
|
||||
),
|
||||
body: Center(
|
||||
child: Container(
|
||||
color: Colors.grey[300],
|
||||
child: Image.memory(data),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> exportSVG(BuildContext context) async {
|
||||
if (_controller.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
key: Key('snackbarSVG'),
|
||||
content: Text('No content'),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final SvgPicture data = _controller.toSVG()!;
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
await push(
|
||||
context,
|
||||
Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('SVG Image'),
|
||||
),
|
||||
body: Center(
|
||||
child: Container(
|
||||
color: Colors.grey[300],
|
||||
child: data,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Signature Demo'),
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
const SizedBox(
|
||||
height: 300,
|
||||
child: Center(
|
||||
child: Text('Big container to test scrolling issues'),
|
||||
),
|
||||
),
|
||||
//SIGNATURE CANVAS
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Signature(
|
||||
key: const Key('signature'),
|
||||
controller: _controller,
|
||||
height: 300,
|
||||
backgroundColor: Colors.grey[300]!,
|
||||
),
|
||||
),
|
||||
Text(_controller.isEmpty
|
||||
? "Signature pad is empty"
|
||||
: "Signature pad is not empty"),
|
||||
const SizedBox(
|
||||
height: 300,
|
||||
child: Center(
|
||||
child: Text('Big container to test scrolling issues'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(color: Colors.black),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
//SHOW EXPORTED IMAGE IN NEW ROUTE
|
||||
IconButton(
|
||||
key: const Key('exportPNG'),
|
||||
icon: const Icon(Icons.image),
|
||||
color: Colors.blue,
|
||||
onPressed: () => exportImage(context),
|
||||
tooltip: 'Export Image',
|
||||
),
|
||||
IconButton(
|
||||
key: const Key('exportSVG'),
|
||||
icon: const Icon(Icons.share),
|
||||
color: Colors.blue,
|
||||
onPressed: () => exportSVG(context),
|
||||
tooltip: 'Export SVG',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.undo),
|
||||
color: Colors.blue,
|
||||
onPressed: () {
|
||||
setState(() => _controller.undo());
|
||||
},
|
||||
tooltip: 'Undo',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.redo),
|
||||
color: Colors.blue,
|
||||
onPressed: () {
|
||||
setState(() => _controller.redo());
|
||||
},
|
||||
tooltip: 'Redo',
|
||||
),
|
||||
//CLEAR CANVAS
|
||||
IconButton(
|
||||
key: const Key('clear'),
|
||||
icon: const Icon(Icons.clear),
|
||||
color: Colors.blue,
|
||||
onPressed: () {
|
||||
setState(() => _controller.clear());
|
||||
},
|
||||
tooltip: 'Clear',
|
||||
),
|
||||
// STOP Edit
|
||||
IconButton(
|
||||
key: const Key('stop'),
|
||||
icon: Icon(
|
||||
_controller.disabled ? Icons.pause : Icons.play_arrow,
|
||||
),
|
||||
color: Colors.blue,
|
||||
onPressed: () {
|
||||
setState(() => _controller.disabled = !_controller.disabled);
|
||||
},
|
||||
tooltip: _controller.disabled ? 'Pause' : 'Play',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -29,6 +29,22 @@ class StructuralMaterialsOfflinePage extends StatefulWidget {
|
|||
final List<String> flooring;
|
||||
final List<String> walls;
|
||||
|
||||
final bool foundationOthers;
|
||||
final bool columOthers;
|
||||
final bool beamsOthers;
|
||||
final bool tfOthers;
|
||||
final bool roofOthers;
|
||||
final bool flooringOthers;
|
||||
final bool wpOthers;
|
||||
|
||||
final Function(bool) updateFoundationOthers;
|
||||
final Function(bool) updateColumOthers;
|
||||
final Function(bool) updateBeamsOthers;
|
||||
final Function(bool) updateTfOthers;
|
||||
final Function(bool) updateRoofOthers;
|
||||
final Function(bool) updateFlooringOthers;
|
||||
final Function(bool) updateWpOthers;
|
||||
|
||||
final Function(List<String>) updateFoundation;
|
||||
final Function(List<String>) updateColumn;
|
||||
final Function(List<String>) updateBeam;
|
||||
|
@ -55,6 +71,20 @@ class StructuralMaterialsOfflinePage extends StatefulWidget {
|
|||
required this.updateRoof,
|
||||
required this.updateFlooring,
|
||||
required this.updateWalls,
|
||||
required this.updateFoundationOthers,
|
||||
required this.updateColumOthers,
|
||||
required this.updateBeamsOthers,
|
||||
required this.updateTfOthers,
|
||||
required this.updateRoofOthers,
|
||||
required this.updateFlooringOthers,
|
||||
required this.updateWpOthers,
|
||||
required this.foundationOthers,
|
||||
required this.columOthers,
|
||||
required this.beamsOthers,
|
||||
required this.tfOthers,
|
||||
required this.roofOthers,
|
||||
required this.flooringOthers,
|
||||
required this.wpOthers,
|
||||
// Repeat for other update methods...
|
||||
});
|
||||
|
||||
|
@ -72,13 +102,6 @@ class _StructuralMaterialsOfflinePage
|
|||
// List<String> roof = [];
|
||||
// List<String> flooring = [];
|
||||
// List<String> walls = [];
|
||||
bool foundationOthers = false;
|
||||
bool columOthers = false;
|
||||
bool beamsOthers = false;
|
||||
bool tfOthers = false;
|
||||
bool roofOthers = false;
|
||||
bool flooringOthers = false;
|
||||
bool wpOthers = false;
|
||||
|
||||
List<MaterialOption> columnOptions = [
|
||||
MaterialOption('steel', 'Steel'),
|
||||
|
@ -114,10 +137,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: foundationOthers,
|
||||
value: widget.foundationOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
foundationOthers = value!;
|
||||
widget.updateFoundationOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -127,9 +150,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: foundationOthers,
|
||||
child: customTextField(
|
||||
"Enter other foundation", "", "other_foundation"),
|
||||
visible: widget.foundationOthers,
|
||||
child: customTextField("Enter other foundation", "",
|
||||
"other_foundation", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -151,10 +174,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: columOthers,
|
||||
value: widget.columOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
columOthers = value!;
|
||||
widget.updateColumOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -164,9 +187,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: columOthers,
|
||||
child:
|
||||
customTextField("Enter other columns", "", "other_column"),
|
||||
visible: widget.columOthers,
|
||||
child: customTextField("Enter other columns", "",
|
||||
"other_column", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -188,10 +211,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: beamsOthers,
|
||||
value: widget.beamsOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
beamsOthers = value!;
|
||||
widget.updateBeamsOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -201,8 +224,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: beamsOthers,
|
||||
child: customTextField("Enter other beam/s", "", "other_beam"),
|
||||
visible: widget.beamsOthers,
|
||||
child: customTextField(
|
||||
"Enter other beam/s", "", "other_beam", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -224,10 +248,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: tfOthers,
|
||||
value: widget.tfOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
tfOthers = value!;
|
||||
widget.updateTfOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -237,9 +261,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: tfOthers,
|
||||
child: customTextField(
|
||||
"Enter other truss framing/s", "", "other_tf"),
|
||||
visible: widget.tfOthers,
|
||||
child: customTextField("Enter other truss framing/s", "",
|
||||
"other_tf", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -261,10 +285,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: roofOthers,
|
||||
value: widget.roofOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
roofOthers = value!;
|
||||
widget.updateRoofOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -274,8 +298,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: roofOthers,
|
||||
child: customTextField("Enter other roof/s", "", "other_roof"),
|
||||
visible: widget.roofOthers,
|
||||
child: customTextField(
|
||||
"Enter other roof/s", "", "other_roof", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -306,10 +331,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: flooringOthers,
|
||||
value: widget.flooringOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
flooringOthers = value!;
|
||||
widget.updateFlooringOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -319,9 +344,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: flooringOthers,
|
||||
child: customTextField(
|
||||
"Enter other flooring/s", "", "other_flooring"),
|
||||
visible: widget.flooringOthers,
|
||||
child: customTextField("Enter other flooring/s", "",
|
||||
"other_flooring", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -349,10 +374,10 @@ class _StructuralMaterialsOfflinePage
|
|||
const Text('Others'),
|
||||
Checkbox(
|
||||
checkColor: Colors.white,
|
||||
value: wpOthers,
|
||||
value: widget.wpOthers,
|
||||
onChanged: (bool? value) {
|
||||
structuralState(() {
|
||||
wpOthers = value!;
|
||||
widget.updateWpOthers(value!);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
@ -362,9 +387,9 @@ class _StructuralMaterialsOfflinePage
|
|||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: wpOthers,
|
||||
child: customTextField(
|
||||
"Enter other walls & partition/s", "", "other_wp"),
|
||||
visible: widget.wpOthers,
|
||||
child: customTextField("Enter other walls & partition/s", "",
|
||||
"other_wp", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -405,9 +430,7 @@ class _StructuralMaterialsOfflinePage
|
|||
{
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
|
||||
context
|
||||
.read<StructuralMaterialOfflineBloc>()
|
||||
.add(
|
||||
context.read<StructuralMaterialOfflineBloc>().add(
|
||||
AddStructuralMaterial(
|
||||
id: 1,
|
||||
bldgapprDetailsId: tempID.getInt('tempid')!,
|
||||
|
@ -415,43 +438,48 @@ class _StructuralMaterialsOfflinePage
|
|||
assessedByName: '',
|
||||
dateCreated: '',
|
||||
dateModified: '',
|
||||
foundation: foundationOthers
|
||||
foundation: widget.foundationOthers
|
||||
? [
|
||||
offlineBldgKey.currentState!
|
||||
.value['other_foundation']
|
||||
]
|
||||
: widget.foundation,
|
||||
columns: columOthers
|
||||
columns: widget
|
||||
.columOthers
|
||||
? [
|
||||
offlineBldgKey.currentState!
|
||||
.value['other_column']
|
||||
offlineBldgKey
|
||||
.currentState!.value['other_column']
|
||||
]
|
||||
: widget.column,
|
||||
beams: beamsOthers
|
||||
beams:
|
||||
widget
|
||||
.beamsOthers
|
||||
? [
|
||||
offlineBldgKey
|
||||
.currentState!.value['other_beam']
|
||||
]
|
||||
: widget.beam,
|
||||
trussFraming: tfOthers
|
||||
trussFraming: widget.tfOthers
|
||||
? [
|
||||
offlineBldgKey
|
||||
.currentState!.value['other_tf']
|
||||
]
|
||||
: widget.trussFraming,
|
||||
roof: roofOthers
|
||||
roof:
|
||||
widget.roofOthers
|
||||
? [
|
||||
offlineBldgKey
|
||||
.currentState!.value['other_roof']
|
||||
]
|
||||
: widget.roof,
|
||||
flooring: flooringOthers
|
||||
flooring:
|
||||
widget.flooringOthers
|
||||
? [
|
||||
offlineBldgKey.currentState!
|
||||
.value['other_flooring']
|
||||
]
|
||||
: widget.flooring,
|
||||
walls: wpOthers
|
||||
walls: widget.wpOthers
|
||||
? [
|
||||
offlineBldgKey
|
||||
.currentState!.value['other_wp']
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Pushes a widget to a new route.
|
||||
Future push(context, widget) {
|
||||
return Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return widget;
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
|
@ -31,7 +31,7 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
bool isSecondHand = false;
|
||||
TextEditingController textEditingController = TextEditingController();
|
||||
double _unitBase = 0;
|
||||
int _areaValue = 0;
|
||||
double _areaValue = 0;
|
||||
double _depValue = 0;
|
||||
double _unitValue = 0;
|
||||
double _marketValue = 0;
|
||||
|
@ -106,6 +106,9 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: SizedBox(
|
||||
height: 45,
|
||||
width: 300,
|
||||
child: FormBuilderDropdown(
|
||||
name: 'extra_item',
|
||||
autofocus: false,
|
||||
|
@ -125,10 +128,17 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.minBaseUnitvalPercent
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'buccValue': (double.parse(
|
||||
value.minBaseUnitvalPercent!) *
|
||||
100)
|
||||
.toString()
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.minBaseUnitvalPercent});
|
||||
}
|
||||
if (value.maxBaseUnitvalPercent != '0.00') {
|
||||
setState(() {
|
||||
|
@ -137,10 +147,17 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'unitValue': value.maxBaseUnitvalPercent
|
||||
});
|
||||
formKey.currentState!.patchValue({
|
||||
'buccValue': (double.parse(
|
||||
value.maxBaseUnitvalPercent!) *
|
||||
100)
|
||||
.toString()
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.maxBaseUnitvalPercent});
|
||||
}
|
||||
if (value.minUnitvalSqrmtr != '0.00') {
|
||||
setState(() {
|
||||
|
@ -149,10 +166,12 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.minUnitvalSqrmtr});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxUnitvalSqrmtr != '0.00') {
|
||||
setState(() {
|
||||
|
@ -161,10 +180,12 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.maxUnitvalSqrmtr});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.minAddBaseunitval != '0.00') {
|
||||
setState(() {
|
||||
|
@ -173,10 +194,12 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.minAddBaseunitval});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxAddBaseunitval != '0.00') {
|
||||
setState(() {
|
||||
|
@ -185,10 +208,12 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.maxAddBaseunitval});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.minDeductBaserate != '0.00') {
|
||||
setState(() {
|
||||
|
@ -197,10 +222,12 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.minDeductBaserate});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
if (value.maxDeductBaserate != '0.00') {
|
||||
setState(() {
|
||||
|
@ -209,14 +236,17 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
_className = value.componentName!;
|
||||
_classId = value.id!;
|
||||
_withoutBUCC =
|
||||
value.withoutBucc == '1' ? true : false;
|
||||
value.withoutBucc == 1 ? true : false;
|
||||
});
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': value.maxDeductBaserate});
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
|
@ -228,15 +258,11 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
suggestions: widget.unit
|
||||
.map((UnitConstruct unit) =>
|
||||
SearchFieldListItem(
|
||||
unit.bldgType! +
|
||||
' - ' +
|
||||
unit.building,
|
||||
'${unit.bldgType} - ${unit.building}',
|
||||
item: unit,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
unit.bldgType +
|
||||
' - ' +
|
||||
unit.building!.toUpperCase(),
|
||||
'${unit.bldgType} - ${unit.building!.toUpperCase()}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)))
|
||||
|
@ -255,41 +281,26 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
suggestionState: Suggestion.expand,
|
||||
onSuggestionTap: (unit) {
|
||||
setState(() {
|
||||
if (_withoutBUCC) {
|
||||
_unitBase = _unitValue;
|
||||
_structureType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
formKey.currentState!
|
||||
.patchValue({'buccValue': '100'});
|
||||
} else {
|
||||
_unitBase =
|
||||
double.parse(unit.item!.unitValue);
|
||||
_structureType = unit.item!.bldgType +
|
||||
' - ' +
|
||||
unit.item!.building;
|
||||
_structureType =
|
||||
'${unit.item!.bldgType} - ${unit.item!.building}';
|
||||
formKey.currentState!.patchValue(
|
||||
{'unitValue': unit.item!.unitValue});
|
||||
}
|
||||
});
|
||||
focus.unfocus();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
// Container(
|
||||
// margin: const EdgeInsets.only(
|
||||
// left: 0, top: 10, right: 0, bottom: 0),
|
||||
// child: FormBuilderDropdown(
|
||||
// name: 'struc_type',
|
||||
// autofocus: false,
|
||||
// decoration:
|
||||
// normalTextFieldStyle("Structure Type", ""),
|
||||
// items: widget.unit
|
||||
// .map((e) => DropdownMenuItem(
|
||||
// value: e,
|
||||
// child:
|
||||
// Text(e.bldgType + " - " + e.building),
|
||||
// ))
|
||||
// .toList(),
|
||||
// onChanged: (val) {
|
||||
// setState(() {
|
||||
// _unitBase = double.parse(val!.unitValue);
|
||||
// _structureType = val.bldgType;
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
|
@ -299,75 +310,60 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
name: 'unitValue',
|
||||
decoration:
|
||||
normalTextFieldStyle("Unit Value", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: 'buccValue',
|
||||
decoration: normalTextFieldStyle("BUCC", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
onChanged: (value) {
|
||||
// setState(() {
|
||||
// _areaValue = double.parse(value!);
|
||||
// });
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'%',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: 'areaValue',
|
||||
decoration: normalTextFieldStyle("Area", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_areaValue = int.parse(value!);
|
||||
_areaValue = double.parse(value!);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
// FormBuilderTextField(
|
||||
// name: 'depRate',
|
||||
// decoration:
|
||||
// normalTextFieldStyle("Depreciation Rate", ""),
|
||||
// validator: FormBuilderValidators.compose([]),
|
||||
// onChanged: (value) {
|
||||
// setState(() {
|
||||
// _depValue = double.parse(value!);
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// FormBuilderTextField(
|
||||
// name: 'marketValue',
|
||||
// decoration: normalTextFieldStyle(
|
||||
// NumberFormat.currency(
|
||||
// locale: 'en-PH', symbol: "₱")
|
||||
// .format(_totalMarketValue(_unitValue,
|
||||
// _unitBase, _areaValue, _depValue)),
|
||||
// ""),
|
||||
// validator: FormBuilderValidators.compose([]),
|
||||
// onChanged: (value) {
|
||||
// setState(() {
|
||||
// _marketValue = double.parse(value!);
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// Text('Amount of Depreciation'),
|
||||
// const SizedBox(height: 5),
|
||||
// Container(
|
||||
// height: 45.0,
|
||||
// width: double.infinity,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// border: Border.all(
|
||||
// color: Colors.grey,
|
||||
// width: 1.0,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(5.0),
|
||||
// ),
|
||||
// child: Align(
|
||||
// alignment: Alignment.center,
|
||||
// child: Text(NumberFormat.currency(
|
||||
// locale: 'en-PH', symbol: "₱")
|
||||
// .format(_amountofDepreciation(_unitValue,
|
||||
// _unitBase, _areaValue, _depValue)))),
|
||||
// ),
|
||||
|
||||
Visibility(
|
||||
visible: !_withoutBUCC,
|
||||
child: Column(
|
||||
|
@ -451,6 +447,7 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
validator:
|
||||
FormBuilderValidators.compose(
|
||||
[]),
|
||||
keyboardType: TextInputType.phone,
|
||||
onChanged: (value) {
|
||||
// Check if the value is not null before parsing to double
|
||||
if (value != null &&
|
||||
|
@ -486,7 +483,6 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
Text('Market Value'),
|
||||
const SizedBox(height: 5),
|
||||
|
@ -539,8 +535,8 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
className: _className,
|
||||
structType: _structureType,
|
||||
unitValue: _withoutBUCC == true
|
||||
? 0
|
||||
: _unitValue,
|
||||
? 100
|
||||
: _unitValue * 100,
|
||||
baseUnitValue: _unitBase.toString(),
|
||||
area: _areaValue,
|
||||
marketValue:
|
||||
|
@ -574,7 +570,7 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
genCode: "5th"));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -593,7 +589,7 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
|
|||
.add(LoadAdditionalItems());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -371,6 +371,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
validator:
|
||||
FormBuilderValidators.compose(
|
||||
[]),
|
||||
keyboardType: TextInputType.phone,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
|
@ -380,6 +381,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
name: 'areaValue',
|
||||
decoration: normalTextFieldStyle(
|
||||
"Area", ""),
|
||||
keyboardType: TextInputType.phone,
|
||||
validator:
|
||||
FormBuilderValidators.compose(
|
||||
[]),
|
||||
|
@ -537,6 +539,8 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
normalTextFieldStyle(
|
||||
"Unit Value",
|
||||
""),
|
||||
keyboardType:
|
||||
TextInputType.phone,
|
||||
validator:
|
||||
FormBuilderValidators
|
||||
.compose([]),
|
||||
|
@ -688,7 +692,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -709,7 +713,7 @@ class _AddExtraItemsOffline extends State<AddExtraItemsOffline> {
|
|||
const LoadAdditionalItems());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -67,9 +67,7 @@ class _AdditionalItemEditPageOffline
|
|||
if (state is AdditionalItemsLoaded) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 500,
|
||||
child: Expanded(
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
|
@ -167,8 +165,7 @@ class _AdditionalItemEditPageOffline
|
|||
onTap: () {
|
||||
confirmAlertWithCancel(
|
||||
context,
|
||||
() =>
|
||||
deleteItem(dataRow.id!),
|
||||
() => deleteItem(dataRow.id!),
|
||||
() => null,
|
||||
'Delete Item?',
|
||||
"Are you sure you want to delete this item?");
|
||||
|
@ -205,7 +202,6 @@ class _AdditionalItemEditPageOffline
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20.0, right: 20.0),
|
||||
child: Row(
|
||||
|
|
|
@ -9,12 +9,14 @@ import 'package:unit2/bloc/offline/offline_passo/admin/unit_construction/unit_co
|
|||
import 'package:unit2/model/offline/offline_profile.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/additional_items_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/building_and_structure.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/flutter_painter_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/general_description_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/landref_location_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/property_appraisal_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/property_assessment_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/property_owner_info_edit.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/structural_materials_edit.dart';
|
||||
import 'package:unit2/utils/alerts.dart';
|
||||
|
||||
import '../../../../../bloc/offline/offline_passo/building/structural_materials_offline.dart/structural_material_offline_bloc.dart';
|
||||
import '../../../../../model/passo/property_info.dart';
|
||||
|
@ -27,13 +29,15 @@ class EditBuildingOffline extends StatefulWidget {
|
|||
final PropertyInfo faas;
|
||||
final String title;
|
||||
final OfflineProfile offlineProfile;
|
||||
final Function loadBldg;
|
||||
|
||||
const EditBuildingOffline(
|
||||
{super.key,
|
||||
required this.title,
|
||||
required this.index,
|
||||
required this.faas,
|
||||
required this.offlineProfile});
|
||||
required this.offlineProfile,
|
||||
required this.loadBldg});
|
||||
@override
|
||||
_EditBuildingOffline createState() => _EditBuildingOffline();
|
||||
}
|
||||
|
@ -42,7 +46,7 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
// THE FOLLOWING TWO VARIABLES ARE REQUIRED TO CONTROL THE STEPPER.
|
||||
int activeStep = 0; // Initial step set to 5.
|
||||
|
||||
int upperBound = 7; // upperBound MUST BE total number of icons minus 1.
|
||||
int upperBound = 8; // upperBound MUST BE total number of icons minus 1.
|
||||
|
||||
void PrevBtn() {
|
||||
setState(() {
|
||||
|
@ -57,7 +61,8 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
}
|
||||
|
||||
void onSAveAll() {
|
||||
return Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
widget.loadBldg();
|
||||
}
|
||||
|
||||
List<String> foundation = [];
|
||||
|
@ -112,7 +117,17 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
confirmAlertWithCancel(
|
||||
context,
|
||||
onSAveAll,
|
||||
() => null,
|
||||
'Cancel Editing?',
|
||||
"Unsaved edited data will not be saved, are you sure you want to exit?"); // Action to perform on back pressed
|
||||
return false;
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
|
@ -147,7 +162,17 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
return Column(
|
||||
children: [
|
||||
NumberStepper(
|
||||
numbers: const [1, 2, 3, 4, 5, 6, 7, 8],
|
||||
numbers: const [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
activeStepColor: primary,
|
||||
numberStyle:
|
||||
const TextStyle(color: Colors.white),
|
||||
|
@ -186,7 +211,8 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
}
|
||||
return Container();
|
||||
},
|
||||
)));
|
||||
))),
|
||||
);
|
||||
}
|
||||
|
||||
// Returns the header text based on the activeStep.
|
||||
|
@ -207,24 +233,28 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
|
|||
case 2:
|
||||
return GeneralDescriptionEditOffline(widget.faas.id!, NextBtn, PrevBtn);
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
return BuildingAndStructureOfflinePage(
|
||||
PrevBtn, NextBtn, widget.offlineProfile);
|
||||
|
||||
case 4:
|
||||
case 3:
|
||||
return FlutterDrawEdit(widget.faas.id!);
|
||||
|
||||
case 5:
|
||||
return StructuralMaterialsPageEditOffline(
|
||||
widget.faas.id!, NextBtn, PrevBtn);
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
return AdditionalItemEditPageOffline(
|
||||
unit, classes, widget.faas.id!, NextBtn, PrevBtn);
|
||||
|
||||
case 6:
|
||||
case 7:
|
||||
return PropertyAppraisalEditPageOffline(
|
||||
widget.faas.id!, NextBtn, PrevBtn);
|
||||
|
||||
case 7:
|
||||
return PropertyAssessmentEditOfflinePage(widget.faas.id!, onSAveAll);
|
||||
case 8:
|
||||
return PropertyAssessmentEditOfflinePage(
|
||||
widget.faas.id!, onSAveAll, widget.offlineProfile);
|
||||
|
||||
default:
|
||||
return Container();
|
||||
|
|
|
@ -0,0 +1,814 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:http/http.dart'; // Removed 'as http'
|
||||
import 'package:path/path.dart'; // For basename function
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter_extensions.dart';
|
||||
import 'package:flutter_painter_v2/flutter_painter_pure.dart';
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:phosphor_flutter/phosphor_flutter.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:unit2/model/passo/floor_sketch.dart';
|
||||
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
|
||||
import '../../../../../sevices/offline/offline_passo/admin/sql_services/sql_services.dart';
|
||||
|
||||
class FlutterDrawEdit extends StatefulWidget {
|
||||
final int tempId;
|
||||
FlutterDrawEdit(this.tempId);
|
||||
|
||||
@override
|
||||
_FlutterPainterExampleState createState() => _FlutterPainterExampleState();
|
||||
}
|
||||
|
||||
class _FlutterPainterExampleState extends State<FlutterDrawEdit> {
|
||||
static const Color red = Color.fromARGB(255, 0, 0, 0);
|
||||
FocusNode textFocusNode = FocusNode();
|
||||
late PainterController controller;
|
||||
ui.Image? backgroundImage;
|
||||
Paint shapePaint = Paint()
|
||||
..strokeWidth = 5
|
||||
..color = Colors.black
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
File? _image;
|
||||
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
static const List<String> imageLinks = [
|
||||
"https://i.imgur.com/btoI5OX.png",
|
||||
"https://i.imgur.com/EXTQFt7.png",
|
||||
"https://i.imgur.com/EDNjJYL.png",
|
||||
"https://i.imgur.com/uQKD6NL.png",
|
||||
"https://i.imgur.com/cMqVRbl.png",
|
||||
"https://i.imgur.com/1cJBAfI.png",
|
||||
"https://i.imgur.com/eNYfHKL.png",
|
||||
"https://i.imgur.com/c4Ag5yt.png",
|
||||
"https://i.imgur.com/GhpCJuf.png",
|
||||
"https://i.imgur.com/XVMeluF.png",
|
||||
"https://i.imgur.com/mt2yO6Z.png",
|
||||
"https://i.imgur.com/rw9XP1X.png",
|
||||
"https://i.imgur.com/pD7foZ8.png",
|
||||
"https://i.imgur.com/13Y3vp2.png",
|
||||
"https://i.imgur.com/ojv3yw1.png",
|
||||
"https://i.imgur.com/f8ZNJJ7.png",
|
||||
"https://i.imgur.com/BiYkHzw.png",
|
||||
"https://i.imgur.com/snJOcEz.png",
|
||||
"https://i.imgur.com/b61cnhi.png",
|
||||
"https://i.imgur.com/FkDFzYe.png",
|
||||
"https://i.imgur.com/P310x7d.png",
|
||||
"https://i.imgur.com/5AHZpua.png",
|
||||
"https://i.imgur.com/tmvJY4r.png",
|
||||
"https://i.imgur.com/PdVfGkV.png",
|
||||
"https://i.imgur.com/1PRzwBf.png",
|
||||
"https://i.imgur.com/VeeMfBS.png",
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller = PainterController(
|
||||
settings: PainterSettings(
|
||||
text: TextSettings(
|
||||
focusNode: textFocusNode,
|
||||
textStyle: const TextStyle(
|
||||
fontWeight: FontWeight.bold, color: red, fontSize: 18),
|
||||
),
|
||||
freeStyle: const FreeStyleSettings(
|
||||
color: red,
|
||||
strokeWidth: 5,
|
||||
),
|
||||
shape: ShapeSettings(
|
||||
paint: shapePaint,
|
||||
),
|
||||
scale: const ScaleSettings(
|
||||
enabled: true,
|
||||
minScale: 1,
|
||||
maxScale: 5,
|
||||
)));
|
||||
// Listen to focus events of the text field
|
||||
textFocusNode.addListener(onFocus);
|
||||
// Initialize background
|
||||
initBackground();
|
||||
}
|
||||
|
||||
/// Fetches image from an [ImageProvider] (in this example, [NetworkImage])
|
||||
/// to use it as a background
|
||||
void initBackground() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final floorSketchSaved = prefs.getBool('floorSketchSaved') ?? false;
|
||||
|
||||
print(floorSketchSaved);
|
||||
|
||||
ui.Image image;
|
||||
|
||||
final String imagePath =
|
||||
'/data/user/0/com.app.rpass/cache/${widget.tempId}.png';
|
||||
image = await _loadImageFromPath(imagePath);
|
||||
|
||||
setState(() {
|
||||
backgroundImage = image;
|
||||
controller.background = image.backgroundDrawable;
|
||||
});
|
||||
}
|
||||
|
||||
/// Updates UI when the focus changes
|
||||
void onFocus() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Future<ui.Image> _loadImageFromPath(String imagePath) async {
|
||||
final file = File(imagePath);
|
||||
final bytes = await file.readAsBytes();
|
||||
final Completer<ui.Image> completer = Completer();
|
||||
ui.decodeImageFromList(bytes, (ui.Image img) {
|
||||
completer.complete(img);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<void> deleteImage(BuildContext context) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final String imagePath =
|
||||
'/data/user/0/com.app.rpass/cache/${widget.tempId}.png';
|
||||
final file = File(imagePath);
|
||||
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image deleted successfully')),
|
||||
);
|
||||
|
||||
final image = await const AssetImage('assets/pngs/white_bg.png').image;
|
||||
setState(() {
|
||||
backgroundImage = image;
|
||||
controller.background = image.backgroundDrawable;
|
||||
});
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image does not exist')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildDefault(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size(double.infinity, kToolbarHeight),
|
||||
// Listen to the controller and update the UI when it updates.
|
||||
child: ValueListenableBuilder<PainterControllerValue>(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, child) {
|
||||
return AppBar(
|
||||
title: child,
|
||||
automaticallyImplyLeading: false, // Disable the back button
|
||||
|
||||
actions: [
|
||||
// Delete the selected drawable
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.trash,
|
||||
),
|
||||
onPressed: controller.selectedObjectDrawable == null
|
||||
? null
|
||||
: removeSelectedDrawable,
|
||||
),
|
||||
// Delete the selected drawable
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.flip,
|
||||
),
|
||||
onPressed: controller.selectedObjectDrawable != null &&
|
||||
controller.selectedObjectDrawable is ImageDrawable
|
||||
? flipSelectedImageDrawable
|
||||
: null,
|
||||
),
|
||||
// Redo action
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.arrowClockwise,
|
||||
),
|
||||
onPressed: controller.canRedo ? redo : null,
|
||||
),
|
||||
// Undo action
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.arrowCounterClockwise,
|
||||
),
|
||||
onPressed: controller.canUndo ? undo : null,
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
// Generate image
|
||||
floatingActionButton: Stack(
|
||||
children: <Widget>[
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: FloatingActionButton(
|
||||
heroTag: 'btn1',
|
||||
child: const Icon(
|
||||
PhosphorIcons.imageFill,
|
||||
),
|
||||
onPressed: () => renderAndDisplayImage(context),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 60.0),
|
||||
child: FloatingActionButton(
|
||||
heroTag: 'btn2',
|
||||
child: const Icon(
|
||||
Icons.delete,
|
||||
),
|
||||
onPressed: () => deleteImage(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Add more FloatingActionButton widgets here if needed
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
if (backgroundImage != null)
|
||||
// Enforces constraints
|
||||
Positioned.fill(
|
||||
child: Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio:
|
||||
backgroundImage!.width / backgroundImage!.height,
|
||||
child: FlutterPainter(
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, __) => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.vertical(top: Radius.circular(20)),
|
||||
color: Colors.white54,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (controller.freeStyleMode !=
|
||||
FreeStyleMode.none) ...[
|
||||
const Divider(),
|
||||
const Text("Free Style Settings"),
|
||||
// Control free style stroke width
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Stroke Width")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 2,
|
||||
max: 25,
|
||||
value: controller.freeStyleStrokeWidth,
|
||||
onChanged: setFreeStyleStrokeWidth),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (controller.freeStyleMode ==
|
||||
FreeStyleMode.draw)
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Color")),
|
||||
// Control free style color hue
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
controller.freeStyleColor)
|
||||
.hue,
|
||||
activeColor:
|
||||
controller.freeStyleColor,
|
||||
onChanged: setFreeStyleColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (textFocusNode.hasFocus) ...[
|
||||
const Divider(),
|
||||
const Text("Text settings"),
|
||||
// Control text font size
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Font Size")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 8,
|
||||
max: 96,
|
||||
value:
|
||||
controller.textStyle.fontSize ?? 14,
|
||||
onChanged: setTextFontSize),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Control text color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(flex: 1, child: Text("Color")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
controller.textStyle.color ??
|
||||
red)
|
||||
.hue,
|
||||
activeColor: controller.textStyle.color,
|
||||
onChanged: setTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (controller.shapeFactory != null) ...[
|
||||
const Divider(),
|
||||
const Text("Shape Settings"),
|
||||
|
||||
// Control text color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Stroke Width")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 2,
|
||||
max: 25,
|
||||
value: controller
|
||||
.shapePaint?.strokeWidth ??
|
||||
shapePaint.strokeWidth,
|
||||
onChanged: (value) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
strokeWidth: value,
|
||||
))),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Control shape color hue
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(flex: 1, child: Text("Color")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Slider.adaptive(
|
||||
min: 0,
|
||||
max: 359.99,
|
||||
value: HSVColor.fromColor(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.color)
|
||||
.hue,
|
||||
activeColor: (controller.shapePaint ??
|
||||
shapePaint)
|
||||
.color,
|
||||
onChanged: (hue) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
color: HSVColor.fromAHSV(
|
||||
1, hue, 1, 1)
|
||||
.toColor(),
|
||||
))),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
flex: 1, child: Text("Fill shape")),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Center(
|
||||
child: Switch(
|
||||
value: (controller.shapePaint ??
|
||||
shapePaint)
|
||||
.style ==
|
||||
PaintingStyle.fill,
|
||||
onChanged: (value) =>
|
||||
setShapeFactoryPaint(
|
||||
(controller.shapePaint ??
|
||||
shapePaint)
|
||||
.copyWith(
|
||||
style: value
|
||||
? PaintingStyle.fill
|
||||
: PaintingStyle.stroke,
|
||||
))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: ValueListenableBuilder(
|
||||
valueListenable: controller,
|
||||
builder: (context, _, __) => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
// Free-style eraser
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.eraser,
|
||||
color: controller.freeStyleMode == FreeStyleMode.erase
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: toggleFreeStyleErase,
|
||||
),
|
||||
// Free-style drawing
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.scribbleLoop,
|
||||
color: controller.freeStyleMode == FreeStyleMode.draw
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: toggleFreeStyleDraw,
|
||||
),
|
||||
// Add text
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
PhosphorIcons.textT,
|
||||
color: textFocusNode.hasFocus
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
onPressed: addText,
|
||||
),
|
||||
// Add sticker image
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
PhosphorIcons.sticker,
|
||||
),
|
||||
onPressed: () => addSticker(context),
|
||||
),
|
||||
// Add shapes
|
||||
if (controller.shapeFactory == null)
|
||||
PopupMenuButton<ShapeFactory?>(
|
||||
tooltip: "Add shape",
|
||||
itemBuilder: (context) => <ShapeFactory, String>{
|
||||
LineFactory(): "Line",
|
||||
ArrowFactory(): "Arrow",
|
||||
DoubleArrowFactory(): "Double Arrow",
|
||||
RectangleFactory(): "Rectangle",
|
||||
OvalFactory(): "Oval",
|
||||
}
|
||||
.entries
|
||||
.map((e) => PopupMenuItem(
|
||||
value: e.key,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
getShapeIcon(e.key),
|
||||
color: Colors.black,
|
||||
),
|
||||
Text(" ${e.value}")
|
||||
],
|
||||
)))
|
||||
.toList(),
|
||||
onSelected: selectShape,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
getShapeIcon(controller.shapeFactory),
|
||||
color: controller.shapeFactory != null
|
||||
? Theme.of(context).primaryColor
|
||||
: null,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
getShapeIcon(controller.shapeFactory),
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
onPressed: () => selectShape(null),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return buildDefault(context);
|
||||
}
|
||||
|
||||
static IconData getShapeIcon(ShapeFactory? shapeFactory) {
|
||||
if (shapeFactory is LineFactory) return PhosphorIcons.lineSegment;
|
||||
if (shapeFactory is ArrowFactory) return PhosphorIcons.arrowUpRight;
|
||||
if (shapeFactory is DoubleArrowFactory) {
|
||||
return PhosphorIcons.arrowsHorizontal;
|
||||
}
|
||||
if (shapeFactory is RectangleFactory) return PhosphorIcons.rectangle;
|
||||
if (shapeFactory is OvalFactory) return PhosphorIcons.circle;
|
||||
return PhosphorIcons.polygon;
|
||||
}
|
||||
|
||||
void undo() {
|
||||
controller.undo();
|
||||
}
|
||||
|
||||
void redo() {
|
||||
controller.redo();
|
||||
}
|
||||
|
||||
void toggleFreeStyleDraw() {
|
||||
controller.freeStyleMode = controller.freeStyleMode != FreeStyleMode.draw
|
||||
? FreeStyleMode.draw
|
||||
: FreeStyleMode.none;
|
||||
}
|
||||
|
||||
void toggleFreeStyleErase() {
|
||||
controller.freeStyleMode = controller.freeStyleMode != FreeStyleMode.erase
|
||||
? FreeStyleMode.erase
|
||||
: FreeStyleMode.none;
|
||||
}
|
||||
|
||||
void addText() {
|
||||
if (controller.freeStyleMode != FreeStyleMode.none) {
|
||||
controller.freeStyleMode = FreeStyleMode.none;
|
||||
}
|
||||
controller.addText();
|
||||
}
|
||||
|
||||
void addSticker(BuildContext context) async {
|
||||
final imageLink = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => const SelectStickerImageDialog(
|
||||
imagesLinks: imageLinks,
|
||||
));
|
||||
if (imageLink == null) return;
|
||||
controller.addImage(
|
||||
await NetworkImage(imageLink).image, const Size(100, 100));
|
||||
}
|
||||
|
||||
void setFreeStyleStrokeWidth(double value) {
|
||||
controller.freeStyleStrokeWidth = value;
|
||||
}
|
||||
|
||||
void setFreeStyleColor(double hue) {
|
||||
controller.freeStyleColor = HSVColor.fromAHSV(1, hue, 1, 1).toColor();
|
||||
}
|
||||
|
||||
void setTextFontSize(double size) {
|
||||
// Set state is just to update the current UI, the [FlutterPainter] UI updates without it
|
||||
setState(() {
|
||||
controller.textSettings = controller.textSettings.copyWith(
|
||||
textStyle:
|
||||
controller.textSettings.textStyle.copyWith(fontSize: size));
|
||||
});
|
||||
}
|
||||
|
||||
void setShapeFactoryPaint(Paint paint) {
|
||||
// Set state is just to update the current UI, the [FlutterPainter] UI updates without it
|
||||
setState(() {
|
||||
controller.shapePaint = paint;
|
||||
});
|
||||
}
|
||||
|
||||
void setTextColor(double hue) {
|
||||
controller.textStyle = controller.textStyle
|
||||
.copyWith(color: HSVColor.fromAHSV(1, hue, 1, 1).toColor());
|
||||
}
|
||||
|
||||
void selectShape(ShapeFactory? factory) {
|
||||
controller.shapeFactory = factory;
|
||||
}
|
||||
|
||||
Future<void> _uploadImage() async {
|
||||
// Create a map with the required fields
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
|
||||
final String imagePath =
|
||||
'/data/user/0/com.app.rpass/cache/${widget.tempId}.png';
|
||||
|
||||
await tempID.setBool('floorSketchSaved', true);
|
||||
var file = File(imagePath);
|
||||
// Map<String, dynamic> detailsMap = {
|
||||
// "bldgappr_details_id": 182, // int8 NOT NULL
|
||||
// "date_created": DateTime.now().toIso8601String(), // timestamptz NULL
|
||||
// "floor_sketch": file.path, // text NULL
|
||||
// "gen_code": "5TH", // varchar(20) NOT NULL
|
||||
// };
|
||||
|
||||
var floorSketchs = FloorSketch(
|
||||
bldgapprDetailsId: widget.tempId,
|
||||
dateCreated: DateTime.now().toIso8601String(),
|
||||
floorSketch: file.path,
|
||||
genCode: "5TH");
|
||||
|
||||
try {
|
||||
// Response response = await _postBuildingDetails(detailsMap);
|
||||
// print(response.body);
|
||||
await SQLServices.instance.createFloorSketch(floorSketchs);
|
||||
// if (response.statusCode == 201) {
|
||||
// print('Upload successful');
|
||||
// } else {
|
||||
// print('Upload failed with status: ${response.statusCode}');
|
||||
// }
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderAndDisplayImage(BuildContext context) async {
|
||||
if (backgroundImage == null) return;
|
||||
|
||||
final backgroundImageSize = Size(
|
||||
backgroundImage!.width.toDouble(),
|
||||
backgroundImage!.height.toDouble(),
|
||||
);
|
||||
|
||||
try {
|
||||
// Render the image
|
||||
final image = await controller.renderImage(backgroundImageSize);
|
||||
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
final imageBytes = byteData!.buffer.asUint8List();
|
||||
final tempID = await SharedPreferences.getInstance();
|
||||
|
||||
// Write the PNG image data to a file
|
||||
final file =
|
||||
File('${(await getTemporaryDirectory()).path}/${widget.tempId}.png');
|
||||
await file.writeAsBytes(imageBytes);
|
||||
|
||||
// Show a dialog with the image
|
||||
// ignore: use_build_context_synchronously
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text('Rendered Image'),
|
||||
content: Image.memory(imageBytes),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('SAVE'),
|
||||
onPressed: () {
|
||||
_uploadImage();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('Close'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// Show a snackbar with the file path
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Image saved to ${file.path}')),
|
||||
);
|
||||
} catch (e) {
|
||||
// Handle potential errors
|
||||
// ignore: use_build_context_synchronously
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Error: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void removeSelectedDrawable() {
|
||||
final selectedDrawable = controller.selectedObjectDrawable;
|
||||
if (selectedDrawable != null) controller.removeDrawable(selectedDrawable);
|
||||
}
|
||||
|
||||
void flipSelectedImageDrawable() {
|
||||
final imageDrawable = controller.selectedObjectDrawable;
|
||||
if (imageDrawable is! ImageDrawable) return;
|
||||
|
||||
controller.replaceDrawable(
|
||||
imageDrawable, imageDrawable.copyWith(flipped: !imageDrawable.flipped));
|
||||
}
|
||||
}
|
||||
|
||||
class RenderedImageDialog extends StatelessWidget {
|
||||
final Future<Uint8List?> imageFuture;
|
||||
final String imagePath = '/data/user/0/com.app.rpass/cache/182.png';
|
||||
|
||||
const RenderedImageDialog({Key? key, required this.imageFuture})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Rendered Image"),
|
||||
content: FutureBuilder<Uint8List?>(
|
||||
future: imageFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const SizedBox(
|
||||
height: 50,
|
||||
child: Center(child: CircularProgressIndicator.adaptive()),
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData || snapshot.data == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
return InteractiveViewer(
|
||||
maxScale: 10, child: Image.memory(snapshot.data!));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SelectStickerImageDialog extends StatelessWidget {
|
||||
final List<String> imagesLinks;
|
||||
|
||||
const SelectStickerImageDialog({Key? key, this.imagesLinks = const []})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Select sticker"),
|
||||
content: imagesLinks.isEmpty
|
||||
? const Text("No images")
|
||||
: FractionallySizedBox(
|
||||
heightFactor: 0.5,
|
||||
child: SingleChildScrollView(
|
||||
child: Wrap(
|
||||
children: [
|
||||
for (final imageLink in imagesLinks)
|
||||
InkWell(
|
||||
onTap: () => Navigator.pop(context, imageLink),
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: 1 / 4,
|
||||
child: Image.network(imageLink),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text("Cancel"),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:unit2/bloc/offline/offline_passo/admin/unit_construction/unit_construction_admin_bloc.dart';
|
||||
import 'package:unit2/bloc/offline/offline_passo/building/general_description/general_description_bloc.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/edit_building.dart';
|
||||
|
@ -38,16 +41,7 @@ class _GeneralDescriptionEditOffline
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
|
||||
child:
|
||||
BlocConsumer<GeneralDescriptionBloc, GeneralDescriptionState>(
|
||||
return BlocConsumer<GeneralDescriptionBloc, GeneralDescriptionState>(
|
||||
listener: (context, state) async {
|
||||
// if (state is GenDescLoading) {
|
||||
// final progress = ProgressHUD.of(context);
|
||||
|
@ -85,10 +79,8 @@ class _GeneralDescriptionEditOffline
|
|||
'bldg_permit': gendesc.bldgPermit,
|
||||
'date_issued': gendesc.dateIssued.toString(),
|
||||
'cct': gendesc.cct.toString(),
|
||||
'coc_issued':
|
||||
gendesc.certCompletionIssued.toString(),
|
||||
'coo_issued':
|
||||
gendesc.certOccupancyIssued.toString(),
|
||||
'coc_issued': gendesc.certCompletionIssued.toString(),
|
||||
'coo_issued': gendesc.certOccupancyIssued.toString(),
|
||||
'date_cnstructed': gendesc.dateIssued.toString(),
|
||||
'date_occupied': gendesc.dateOccupied.toString(),
|
||||
'bldg_age': gendesc.bldgAge.toString(),
|
||||
|
@ -103,65 +95,51 @@ class _GeneralDescriptionEditOffline
|
|||
enabled: true,
|
||||
onChanged: () {
|
||||
offlineBldgEditKey.currentState!.save();
|
||||
debugPrint(offlineBldgEditKey.currentState!.value
|
||||
.toString());
|
||||
debugPrint(
|
||||
offlineBldgEditKey.currentState!.value.toString());
|
||||
},
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
skipDisabled: true,
|
||||
child: Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 0,
|
||||
top: 20,
|
||||
right: 0,
|
||||
bottom: 10),
|
||||
left: 0, top: 20, right: 0, bottom: 10),
|
||||
child: const Text('GENERAL DESCRIPTION',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18),
|
||||
fontWeight: FontWeight.bold, fontSize: 18),
|
||||
textAlign: TextAlign.left),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 0,
|
||||
top: 10,
|
||||
right: 0,
|
||||
bottom: 0),
|
||||
left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: FormBuilderDropdown(
|
||||
name: 'bldg_type',
|
||||
autofocus: false,
|
||||
decoration: normalTextFieldStyle(
|
||||
gendesc.bldgKind ??
|
||||
"Kind of Building",
|
||||
gendesc.bldgKind ?? "Kind of Building",
|
||||
"Kind of Building"),
|
||||
items: state.unit
|
||||
.map((e) => DropdownMenuItem(
|
||||
value: e,
|
||||
child: Text(e.bldgType +
|
||||
'-' +
|
||||
e.building),
|
||||
child:
|
||||
Text(e.bldgType + '-' + e.building),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
customDropDownField("Actual Use", "",
|
||||
'actual_use', actual_use),
|
||||
customDropDownField(
|
||||
"Actual Use", "", 'actual_use', actual_use),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Bldg. Permit No.",
|
||||
"",
|
||||
'bldg_permit'),
|
||||
child: customTextField("Bldg. Permit No.", "",
|
||||
'bldg_permit', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -175,10 +153,10 @@ class _GeneralDescriptionEditOffline
|
|||
customTextField(
|
||||
"Condominium Certificate of Title (CCT)",
|
||||
"",
|
||||
'cct'),
|
||||
'cct',
|
||||
TextInputType.number),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
|
@ -197,8 +175,7 @@ class _GeneralDescriptionEditOffline
|
|||
'coo_issued'))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
|
@ -212,38 +189,30 @@ class _GeneralDescriptionEditOffline
|
|||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customDatTimePicker(
|
||||
"Date Occupied",
|
||||
"",
|
||||
'date_occupied'))
|
||||
"Date Occupied", "", 'date_occupied'))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Bldg. Age", "", 'bldg_age'),
|
||||
child: customTextField("Bldg. Age", "",
|
||||
'bldg_age', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. of storeys",
|
||||
"",
|
||||
'no_of_storeys'))
|
||||
child: customTextField("No. of storeys", "",
|
||||
'no_of_storeys', TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 1st Floor",
|
||||
"",
|
||||
'area_of_1stFl'),
|
||||
child: customTextField("Area of 1st Floor",
|
||||
"", 'area_of_1stFl', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -252,18 +221,19 @@ class _GeneralDescriptionEditOffline
|
|||
child: customTextField(
|
||||
"Area of 2nd Floor",
|
||||
"",
|
||||
'area_of_2ndFl'))
|
||||
'area_of_2ndFl',
|
||||
TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area of 3rd Floor",
|
||||
"",
|
||||
'area_of_3rdFl')),
|
||||
'area_of_3rdFl',
|
||||
TextInputType.phone)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
|
@ -271,20 +241,19 @@ class _GeneralDescriptionEditOffline
|
|||
child: customTextField(
|
||||
"Area of 4th Floor",
|
||||
"",
|
||||
'area_of_4thFl'))
|
||||
'area_of_4thFl',
|
||||
TextInputType.phone))
|
||||
]),
|
||||
customTextField(
|
||||
"Total Area", "", 'total_area'),
|
||||
customTextField("Total Area", "", 'total_area',
|
||||
TextInputType.phone),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
CustomButton(
|
||||
icon: const Icon(
|
||||
Icons.chevron_left_rounded,
|
||||
icon: const Icon(Icons.chevron_left_rounded,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
{
|
||||
|
@ -294,18 +263,15 @@ class _GeneralDescriptionEditOffline
|
|||
},
|
||||
),
|
||||
CustomButton(
|
||||
icon: const Icon(
|
||||
Icons.chevron_right_rounded,
|
||||
icon: const Icon(Icons.chevron_right_rounded,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
{
|
||||
offlineBldgEditKey.currentState!
|
||||
.save();
|
||||
offlineBldgEditKey.currentState!.save();
|
||||
|
||||
var gendescData = GeneralDesc(
|
||||
id: 1,
|
||||
bldgapprDetailsId:
|
||||
widget.tempId,
|
||||
bldgapprDetailsId: widget.tempId,
|
||||
assessedById: "1",
|
||||
assessedByName: 'hhs',
|
||||
bldgKind: offlineBldgEditKey
|
||||
|
@ -318,19 +284,19 @@ class _GeneralDescriptionEditOffline
|
|||
?.value['bldg_type']
|
||||
?.bldgType ??
|
||||
gendesc.strucType,
|
||||
bldgPermit: offlineBldgEditKey.currentState?.value['bldg_permit'] ??
|
||||
bldgPermit: offlineBldgEditKey
|
||||
.currentState
|
||||
?.value['bldg_permit'] ??
|
||||
gendesc.bldgPermit,
|
||||
dateIssued: offlineBldgEditKey.currentState?.value['date_issued'] != null
|
||||
dateIssued: offlineBldgEditKey
|
||||
.currentState
|
||||
?.value['date_issued'] !=
|
||||
null
|
||||
? offlineBldgEditKey.currentState!.value['date_issued']
|
||||
.toString()
|
||||
: gendesc.dateIssued,
|
||||
cct: offlineBldgEditKey.currentState!.value['cct'] ??
|
||||
gendesc.cct,
|
||||
certCompletionIssued:
|
||||
offlineBldgEditKey
|
||||
.currentState!
|
||||
.value['coc_issued']
|
||||
.toString(),
|
||||
cct: offlineBldgEditKey.currentState!.value['cct'] ?? gendesc.cct,
|
||||
certCompletionIssued: offlineBldgEditKey.currentState!.value['coc_issued'].toString(),
|
||||
certOccupancyIssued: offlineBldgEditKey.currentState!.value['coo_issued'].toString(),
|
||||
dateCompleted: offlineBldgEditKey.currentState!.value['date_cnstructed'].toString(),
|
||||
dateOccupied: offlineBldgEditKey.currentState!.value['date_occupied'].toString(),
|
||||
|
@ -345,14 +311,10 @@ class _GeneralDescriptionEditOffline
|
|||
actualUse: offlineBldgEditKey.currentState?.value['actual_use'],
|
||||
unitValue: offlineBldgEditKey.currentState?.value['bldg_type']?.unitValue ?? gendesc.unitValue);
|
||||
|
||||
context
|
||||
.read<
|
||||
GeneralDescriptionBloc>()
|
||||
.add(
|
||||
context.read<GeneralDescriptionBloc>().add(
|
||||
UpdateGeneralDescription(
|
||||
id: widget.tempId,
|
||||
gendesc:
|
||||
gendescData));
|
||||
gendesc: gendescData));
|
||||
|
||||
widget.NextBtn();
|
||||
}
|
||||
|
@ -365,7 +327,6 @@ class _GeneralDescriptionEditOffline
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
|
@ -383,11 +344,6 @@ class _GeneralDescriptionEditOffline
|
|||
// }
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,10 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. / Street", "", 'street'),
|
||||
"No. / Street",
|
||||
"",
|
||||
'street',
|
||||
TextInputType.text),
|
||||
),
|
||||
|
||||
// Expanded(
|
||||
|
@ -254,8 +257,8 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
fontSize: 18),
|
||||
textAlign: TextAlign.center),
|
||||
),
|
||||
customTextField(
|
||||
"Land Owner", "", 'l_owner'),
|
||||
customTextField("Land Owner", "",
|
||||
'l_owner', TextInputType.text),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
|
@ -265,7 +268,8 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
child: customTextField(
|
||||
"OCT/TCT/CLOA No.",
|
||||
"",
|
||||
'oct_tct_cloa'),
|
||||
'oct_tct_cloa',
|
||||
TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -274,7 +278,8 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
child: customTextField(
|
||||
"Survey No.",
|
||||
"",
|
||||
'survey_no'))
|
||||
'survey_no',
|
||||
TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
|
@ -283,14 +288,20 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Lot No.", "", 'lot_no'),
|
||||
"Lot No.",
|
||||
"",
|
||||
'lot_no',
|
||||
TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Blk No.", "", 'blk_no'))
|
||||
"Blk No.",
|
||||
"",
|
||||
'blk_no',
|
||||
TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
|
@ -301,14 +312,18 @@ class _BldgLocLandRefEditOffline extends State<BldgLocLandRefEditOffline> {
|
|||
child: customTextField(
|
||||
"TD / ARP No.",
|
||||
"",
|
||||
'l_td_arp'),
|
||||
'l_td_arp',
|
||||
TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Area", "", 'area'))
|
||||
"Area",
|
||||
"",
|
||||
'area',
|
||||
TextInputType.phone))
|
||||
]),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:unit2/bloc/offline/offline_passo/building/assessment_offline/bld
|
|||
import 'package:unit2/screens/offline/passo/building/edit/edit_building.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
|
||||
import '../../../../../model/offline/offline_profile.dart';
|
||||
import '../../../../../model/passo/memoranda.dart';
|
||||
import '../../../../../model/passo/property_assessment.dart';
|
||||
import '../../../../../model/passo/property_assessment_edit.dart';
|
||||
|
@ -22,7 +23,9 @@ import '../../../../../widgets/passo/custom_formBuilder_fields.dart';
|
|||
class PropertyAssessmentEditOfflinePage extends StatefulWidget {
|
||||
int tempId;
|
||||
Function onSAve;
|
||||
PropertyAssessmentEditOfflinePage(this.tempId, this.onSAve);
|
||||
final OfflineProfile offlineProfile;
|
||||
PropertyAssessmentEditOfflinePage(
|
||||
this.tempId, this.onSAve, this.offlineProfile);
|
||||
@override
|
||||
_PropertyAssessmentEditOfflinePage createState() =>
|
||||
_PropertyAssessmentEditOfflinePage();
|
||||
|
@ -471,6 +474,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var width = MediaQuery.of(context).size.width;
|
||||
return ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
|
@ -487,7 +491,9 @@ class _PropertyAssessmentEditOfflinePage
|
|||
isTaxable = state.assessment.taxable == '1' ? true : false;
|
||||
isExempt = state.assessment.exempt == '1' ? true : false;
|
||||
memorandaController.text = state.assessment.memoranda;
|
||||
_memoranda = state.assessment.memoranda;
|
||||
noteController.text = state.assessment.note;
|
||||
_notes = state.assessment.note;
|
||||
appraised_by_designation =
|
||||
state.assessment.appraisedbyDesignation!;
|
||||
rec_by_designation = state.assessment.recommendapprDesignation!;
|
||||
|
@ -567,7 +573,6 @@ class _PropertyAssessmentEditOfflinePage
|
|||
},
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
skipDisabled: true,
|
||||
child: Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
|
@ -583,7 +588,9 @@ class _PropertyAssessmentEditOfflinePage
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 20),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
|
@ -636,7 +643,10 @@ class _PropertyAssessmentEditOfflinePage
|
|||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
SingleChildScrollView(
|
||||
scrollDirection:
|
||||
Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.spaceAround,
|
||||
|
@ -650,20 +660,33 @@ class _PropertyAssessmentEditOfflinePage
|
|||
'',
|
||||
'qtr',
|
||||
quarter)),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
height: 50,
|
||||
child: customTextField(
|
||||
'Sworn Statement No.',
|
||||
'',
|
||||
'sworn_statement')),
|
||||
'sworn_statement',
|
||||
TextInputType
|
||||
.number)),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 90,
|
||||
height: 50,
|
||||
child: customTextField(
|
||||
'Year', '', 'yr')),
|
||||
'Year',
|
||||
'',
|
||||
'yr',
|
||||
TextInputType
|
||||
.number)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -672,47 +695,43 @@ class _PropertyAssessmentEditOfflinePage
|
|||
Divider(
|
||||
thickness: 2,
|
||||
),
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SizedBox(
|
||||
child: Row(
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 150,
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
width: width / 2 - 100,
|
||||
height: 50,
|
||||
child:
|
||||
customDatTimePicker(
|
||||
child: customDatTimePicker(
|
||||
'Date Received',
|
||||
'',
|
||||
'date_received')),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 150,
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
width: width / 2 - 100,
|
||||
height: 50,
|
||||
child:
|
||||
customDatTimePicker(
|
||||
child: customDatTimePicker(
|
||||
'Date of Entry',
|
||||
'',
|
||||
'date_of_entry'))
|
||||
'date_of_entry')),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Align(
|
||||
const Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'APPRAISED/ASSESSED BY:',
|
||||
style: TextStyle(
|
||||
fontWeight:
|
||||
FontWeight.bold),
|
||||
fontWeight: FontWeight.bold),
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
),
|
||||
|
@ -729,8 +748,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -756,13 +774,14 @@ class _PropertyAssessmentEditOfflinePage
|
|||
signatories,
|
||||
child:
|
||||
ListTile(
|
||||
title:
|
||||
Text(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
TextOverflow
|
||||
.ellipsis,
|
||||
textAlign:
|
||||
TextAlign.center,
|
||||
TextAlign
|
||||
.center,
|
||||
),
|
||||
)))
|
||||
.toList(),
|
||||
|
@ -772,8 +791,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
searchStyle:
|
||||
TextStyle(),
|
||||
searchStyle: TextStyle(),
|
||||
|
||||
////agency suggestion tap
|
||||
focusNode:
|
||||
|
@ -813,8 +831,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors
|
||||
.grey, // You can set the color here
|
||||
|
@ -878,8 +895,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -905,13 +921,14 @@ class _PropertyAssessmentEditOfflinePage
|
|||
signatories,
|
||||
child:
|
||||
ListTile(
|
||||
title:
|
||||
Text(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
TextOverflow
|
||||
.ellipsis,
|
||||
textAlign:
|
||||
TextAlign.center,
|
||||
TextAlign
|
||||
.center,
|
||||
),
|
||||
)))
|
||||
.toList(),
|
||||
|
@ -921,8 +938,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
searchStyle:
|
||||
TextStyle(),
|
||||
searchStyle: TextStyle(),
|
||||
|
||||
////agency suggestion tap
|
||||
focusNode: recByFocus,
|
||||
|
@ -960,8 +976,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors
|
||||
.grey, // You can set the color here
|
||||
|
@ -1025,8 +1040,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
EdgeInsets.fromLTRB(
|
||||
20, 0, 0, 0),
|
||||
margin: const EdgeInsets
|
||||
.fromLTRB(
|
||||
0, 10, 0, 0),
|
||||
.fromLTRB(0, 10, 0, 0),
|
||||
width: 250,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
|
@ -1052,13 +1066,14 @@ class _PropertyAssessmentEditOfflinePage
|
|||
signatories,
|
||||
child:
|
||||
ListTile(
|
||||
title:
|
||||
Text(
|
||||
title: Text(
|
||||
'${signatories.firstname} ${signatories.middlename} ${signatories.lastname!}',
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
TextOverflow
|
||||
.ellipsis,
|
||||
textAlign:
|
||||
TextAlign.center,
|
||||
TextAlign
|
||||
.center,
|
||||
),
|
||||
)))
|
||||
.toList(),
|
||||
|
@ -1068,12 +1083,10 @@ class _PropertyAssessmentEditOfflinePage
|
|||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
searchStyle:
|
||||
TextStyle(),
|
||||
searchStyle: TextStyle(),
|
||||
|
||||
////agency suggestion tap
|
||||
focusNode:
|
||||
apprvdByFocus,
|
||||
focusNode: apprvdByFocus,
|
||||
suggestionState:
|
||||
Suggestion.expand,
|
||||
onSuggestionTap:
|
||||
|
@ -1085,8 +1098,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
appraised.item!
|
||||
.designation;
|
||||
});
|
||||
apprvdByFocus
|
||||
.unfocus();
|
||||
apprvdByFocus.unfocus();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -1109,8 +1121,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
0, 10, 0, 0),
|
||||
width: 250,
|
||||
height: 50,
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors
|
||||
.grey, // You can set the color here
|
||||
|
@ -1131,6 +1142,9 @@ class _PropertyAssessmentEditOfflinePage
|
|||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
|
@ -1166,11 +1180,10 @@ class _PropertyAssessmentEditOfflinePage
|
|||
height: 50,
|
||||
child: SearchField(
|
||||
itemHeight: 200,
|
||||
controller:
|
||||
memorandaController,
|
||||
controller: memorandaController,
|
||||
suggestions: memoranda
|
||||
.map((Memoranda
|
||||
memoranda) =>
|
||||
.map(
|
||||
(Memoranda memoranda) =>
|
||||
SearchFieldListItem(
|
||||
'${memoranda.memoranda}',
|
||||
item:
|
||||
|
@ -1251,8 +1264,8 @@ class _PropertyAssessmentEditOfflinePage
|
|||
color: Colors.grey,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(5),
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
),
|
||||
enabledBorder:
|
||||
OutlineInputBorder(
|
||||
|
@ -1262,8 +1275,8 @@ class _PropertyAssessmentEditOfflinePage
|
|||
width: 1,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(5),
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1311,8 +1324,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
errorText:
|
||||
"This field is required"),
|
||||
searchInputDecoration:
|
||||
InputDecoration()
|
||||
.copyWith(
|
||||
InputDecoration().copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down),
|
||||
),
|
||||
|
@ -1354,8 +1366,8 @@ class _PropertyAssessmentEditOfflinePage
|
|||
color: Colors.grey,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(5),
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
),
|
||||
enabledBorder:
|
||||
OutlineInputBorder(
|
||||
|
@ -1365,8 +1377,8 @@ class _PropertyAssessmentEditOfflinePage
|
|||
width: 1,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(5),
|
||||
BorderRadius.circular(
|
||||
5),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1383,8 +1395,7 @@ class _PropertyAssessmentEditOfflinePage
|
|||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primary,
|
||||
foregroundColor:
|
||||
Colors.red),
|
||||
foregroundColor: Colors.red),
|
||||
child: const SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
|
@ -1395,20 +1406,25 @@ class _PropertyAssessmentEditOfflinePage
|
|||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
textAlign:
|
||||
TextAlign.center,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
offlineBldgEditKey.currentState!
|
||||
.save();
|
||||
var ass = PropertyAssessment(
|
||||
id: 1,
|
||||
bldgapprDetailsId:
|
||||
widget.tempId,
|
||||
assessedById: "",
|
||||
assessedByName: "",
|
||||
dateCreated: '',
|
||||
dateModified: '',
|
||||
assessedById: widget
|
||||
.offlineProfile.id
|
||||
.toString(),
|
||||
assessedByName: widget
|
||||
.offlineProfile
|
||||
.firstName!,
|
||||
dateCreated: "None",
|
||||
dateModified: "None",
|
||||
actualUse:
|
||||
assessment.actualUse,
|
||||
marketValue: '0.0',
|
||||
|
@ -1426,32 +1442,26 @@ class _PropertyAssessmentEditOfflinePage
|
|||
yr: offlineBldgEditKey
|
||||
.currentState!
|
||||
.value['yr'],
|
||||
appraisedbyName:
|
||||
appraised_by,
|
||||
appraisedbyDate: offlineBldgEditKey
|
||||
.currentState!
|
||||
.value['app_date']
|
||||
.toString(),
|
||||
recommendapprName: rec_by,
|
||||
recommendapprDate:
|
||||
offlineBldgEditKey
|
||||
.currentState!
|
||||
.value['rec_date']
|
||||
.toString(),
|
||||
approvedbyName:
|
||||
approved_by,
|
||||
approvedbyDate:
|
||||
offlineBldgEditKey.currentState!.value['approve_date'].toString(),
|
||||
appraisedbyName: appraised_by == ""
|
||||
? assessment
|
||||
.appraisedbyName
|
||||
: appraised_by,
|
||||
appraisedbyDate:
|
||||
offlineBldgEditKey.currentState!.value['app_date'].toString(),
|
||||
recommendapprName: rec_by == "" ? assessment.recommendapprName : rec_by,
|
||||
recommendapprDate: offlineBldgEditKey.currentState!.value['rec_date'].toString(),
|
||||
approvedbyName: approved_by == "" ? assessment.approvedbyName : approved_by,
|
||||
approvedbyDate: offlineBldgEditKey.currentState!.value['approve_date'].toString(),
|
||||
memoranda: _memoranda,
|
||||
note: _notes,
|
||||
swornstatementNo: offlineBldgEditKey.currentState!.value['sworn_statement'],
|
||||
dateReceived: offlineBldgEditKey.currentState!.value['date_received'].toString(),
|
||||
entryDateAssessment: offlineBldgEditKey.currentState!.value['date_of_entry'].toString(),
|
||||
entryDateBy: '',
|
||||
entryDateBy: "none",
|
||||
genCode: '5th',
|
||||
appraisedbyDesignation: '',
|
||||
approvedbyDesignation: '',
|
||||
recommendapprDesignation: '');
|
||||
appraisedbyDesignation: appraised_by_designation == "" ? assessment.appraisedbyDesignation : appraised_by_designation,
|
||||
approvedbyDesignation: approved_by_designation == "" ? assessment.approvedbyDesignation : approved_by_designation,
|
||||
recommendapprDesignation: rec_by_designation == "" ? assessment.recommendapprDesignation : rec_by_designation);
|
||||
|
||||
context
|
||||
.read<
|
||||
|
@ -1466,10 +1476,11 @@ class _PropertyAssessmentEditOfflinePage
|
|||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -46,12 +46,8 @@ class _PropertyOwnerInfoEditOffline
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
FormBuilder(
|
||||
|
@ -75,8 +71,7 @@ class _PropertyOwnerInfoEditOffline
|
|||
enabled: true,
|
||||
onChanged: () {
|
||||
offlineBldgEditKey.currentState!.save();
|
||||
debugPrint(
|
||||
offlineBldgEditKey.currentState!.value.toString());
|
||||
debugPrint(offlineBldgEditKey.currentState!.value.toString());
|
||||
},
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
skipDisabled: true,
|
||||
|
@ -88,8 +83,7 @@ class _PropertyOwnerInfoEditOffline
|
|||
left: 0, top: 20, right: 0, bottom: 10),
|
||||
child: const Text('PROPERTY OWNER INFO',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18),
|
||||
fontWeight: FontWeight.bold, fontSize: 18),
|
||||
textAlign: TextAlign.left),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
|
@ -104,89 +98,89 @@ class _PropertyOwnerInfoEditOffline
|
|||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"ARP No. / TD No.", "", 'arp_td')),
|
||||
child: customTextField("ARP No. / TD No.", "",
|
||||
'arp_td', TextInputType.phone)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Pin", "", 'pin')),
|
||||
child: customTextField(
|
||||
"Pin", "", 'pin', TextInputType.phone)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"First Name", "", 'fname'),
|
||||
child: customTextField("First Name", "", 'fname',
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Middle Name", "", 'mname',
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Middle Name", "", 'mname'),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Last Name", "", 'lname'),
|
||||
"Last Name", "", 'lname', TextInputType.text),
|
||||
)
|
||||
]),
|
||||
customDatTimePicker("Birthday", "", "bday"),
|
||||
customTextField("Address", "", 'address'),
|
||||
customTextField(
|
||||
"Address", "", 'address', TextInputType.text),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Tel No.", "", 'tel_no'),
|
||||
"Tel No.", "", 'tel_no', TextInputType.phone),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", 'tin'))
|
||||
child: customTextField(
|
||||
"TIN", "", 'tin', TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Administrator / Benificial User",
|
||||
"",
|
||||
'benificiary'),
|
||||
'benificiary',
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"TIN", "", 'benificiary_tin'))
|
||||
child: customTextField("TIN", "",
|
||||
'benificiary_tin', TextInputType.phone))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Address", "", 'benificiary_address'),
|
||||
child: customTextField("Address", "",
|
||||
'benificiary_address', TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Tel No.", "", 'benificiary_telno'))
|
||||
child: customTextField("Tel No.", "",
|
||||
'benificiary_telno', TextInputType.phone))
|
||||
]),
|
||||
const SizedBox(height: 25),
|
||||
SizedBox(
|
||||
|
@ -197,25 +191,24 @@ class _PropertyOwnerInfoEditOffline
|
|||
onPressed: () {
|
||||
var property_info = PropertyInfo(
|
||||
id: widget.faas.id,
|
||||
transCode: offlineBldgEditKey.currentState
|
||||
?.value['transaction_code']
|
||||
transCode: offlineBldgEditKey
|
||||
.currentState?.value['transaction_code']
|
||||
.toString() ??
|
||||
widget.faas.transCode,
|
||||
assessedById: '1',
|
||||
assessedByName: 'cyril',
|
||||
tdn: offlineBldgEditKey
|
||||
.currentState!.value['arp_td'] ??
|
||||
tdn: offlineBldgEditKey.currentState!.value['arp_td'] ??
|
||||
widget.faas.tdn,
|
||||
pin: offlineBldgEditKey.currentState!.value['pin'] ??
|
||||
widget.faas.pin,
|
||||
fname: offlineBldgEditKey
|
||||
.currentState!.value['fname'] ??
|
||||
fname: offlineBldgEditKey.currentState!.value['fname'] ??
|
||||
widget.faas.fname,
|
||||
mname:
|
||||
offlineBldgEditKey.currentState!.value['mname'] ??
|
||||
mname: offlineBldgEditKey.currentState!.value['mname'] ??
|
||||
widget.faas.mname,
|
||||
bday: offlineBldgEditKey.currentState!.value['bday'].toString(),
|
||||
lname: offlineBldgEditKey.currentState!.value['lname'] ?? widget.faas.lname,
|
||||
bday: offlineBldgEditKey.currentState!.value['bday']
|
||||
.toString(),
|
||||
lname: offlineBldgEditKey.currentState!.value['lname'] ??
|
||||
widget.faas.lname,
|
||||
address: offlineBldgEditKey.currentState!.value['address'] ?? widget.faas.address,
|
||||
telno: offlineBldgEditKey.currentState!.value['tel_no'] ?? widget.faas.telno,
|
||||
tin: offlineBldgEditKey.currentState!.value['tin'] ?? widget.faas.tin,
|
||||
|
@ -238,9 +231,6 @@ class _PropertyOwnerInfoEditOffline
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,8 +103,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: foundationOthers,
|
||||
child: customTextField(
|
||||
"Enter other foundation", "", "other_foundation"),
|
||||
child: customTextField("Enter other foundation", "",
|
||||
"other_foundation", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -145,8 +145,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: columOthers,
|
||||
child: customTextField(
|
||||
"Enter other columns", "", "other_column"),
|
||||
child: customTextField("Enter other columns", "",
|
||||
"other_column", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -186,8 +186,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: beamsOthers,
|
||||
child:
|
||||
customTextField("Enter other beam/s", "", "other_beam"),
|
||||
child: customTextField("Enter other beam/s", "",
|
||||
"other_beam", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -227,8 +227,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: tfOthers,
|
||||
child: customTextField(
|
||||
"Enter other truss framing/s", "", "other_tf"),
|
||||
child: customTextField("Enter other truss framing/s", "",
|
||||
"other_tf", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -269,8 +269,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: roofOthers,
|
||||
child:
|
||||
customTextField("Enter other roof/s", "", "other_roof"),
|
||||
child: customTextField("Enter other roof/s", "",
|
||||
"other_roof", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -319,8 +319,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: flooringOthers,
|
||||
child: customTextField(
|
||||
"Enter other flooring/s", "", "other_flooring"),
|
||||
child: customTextField("Enter other flooring/s", "",
|
||||
"other_flooring", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
@ -367,8 +367,8 @@ class _StructuralMaterialsPageEditOffline
|
|||
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0),
|
||||
child: Visibility(
|
||||
visible: wpOthers,
|
||||
child: customTextField(
|
||||
"Enter other walls & partition/s", "", "other_wp"),
|
||||
child: customTextField("Enter other walls & partition/s",
|
||||
"", "other_wp", TextInputType.text),
|
||||
replacement: DropDownMultiSelect(
|
||||
selected_values_style: TextStyle(color: Colors.black),
|
||||
onChanged: (List<String> x) {
|
||||
|
|
|
@ -31,6 +31,8 @@ import 'package:unit2/model/passo/property_appraisal.dart';
|
|||
import 'package:unit2/model/passo/property_assessment.dart';
|
||||
import 'package:unit2/model/passo/property_info.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/add_building.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/drawing_pad.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/add/flutter_painter.dart';
|
||||
import 'package:unit2/screens/offline/passo/building/edit/edit_building.dart';
|
||||
import 'package:unit2/screens/offline/passo/land/add/add_land.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
|
@ -127,7 +129,8 @@ class BuildingHomeOffline extends StatelessWidget {
|
|||
index,
|
||||
deleteItem,
|
||||
state.propertyInfos.length,
|
||||
offlineProfile);
|
||||
offlineProfile,
|
||||
triggerLoadBldgFaas);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -140,6 +143,20 @@ class BuildingHomeOffline extends StatelessWidget {
|
|||
"You don't have any building faas added. Please click + to add");
|
||||
}
|
||||
}
|
||||
if (state is PropertyOwnerInfoErrorState) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// Perform actions after the current build frame; safe place for setState or context-dependent actions
|
||||
confirmAlertWithCancelCustom(
|
||||
context,
|
||||
() => context.read<CrudBloc>().add(
|
||||
UploadBuildingFaas(offlineProfile: offlineProfile)),
|
||||
() => context.read<CrudBloc>().add(FetchTodos()),
|
||||
"Sync unsuccesful!",
|
||||
"Please try again!",
|
||||
"Retry",
|
||||
"Cancel");
|
||||
});
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
)),
|
||||
|
@ -294,7 +311,13 @@ class BuildingHomeOffline extends StatelessWidget {
|
|||
color: primary,
|
||||
),
|
||||
label: 'Machinery',
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const DrawingScreen()),
|
||||
);
|
||||
},
|
||||
),
|
||||
SpeedDialChild(
|
||||
child: const Icon(
|
||||
|
@ -314,7 +337,7 @@ class BuildingHomeOffline extends StatelessWidget {
|
|||
}
|
||||
|
||||
Card _listCard(PropertyInfo property_info, context, index, deleteItem,
|
||||
bldgLength, offlineProfile) {
|
||||
bldgLength, offlineProfile, triggerLoadLandFaas) {
|
||||
return Card(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
|
@ -394,7 +417,8 @@ Card _listCard(PropertyInfo property_info, context, index, deleteItem,
|
|||
index: index,
|
||||
faas: property_info,
|
||||
title: 'Bldg & Structure Edit',
|
||||
offlineProfile: offlineProfile),
|
||||
offlineProfile: offlineProfile,
|
||||
loadBldg: triggerLoadLandFaas),
|
||||
);
|
||||
}));
|
||||
},
|
||||
|
@ -433,7 +457,14 @@ Card _listCard(PropertyInfo property_info, context, index, deleteItem,
|
|||
),
|
||||
SizedBox(height: 5),
|
||||
Text(
|
||||
'${property_info.tdn}',
|
||||
'TDN: ${property_info.tdn}',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
Text(
|
||||
'Uploaded on: ${property_info.dateSynced == null ? '--' : property_info.dateSynced}',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
),
|
||||
|
|
|
@ -366,7 +366,8 @@ class _AddLandAppraisalOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -389,7 +390,8 @@ class _AddLandAppraisalOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -291,7 +291,7 @@ class _AddPropertyAssessmentOfflineModal
|
|||
totalAssessedval: '0'));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -311,7 +311,7 @@ class _AddPropertyAssessmentOfflineModal
|
|||
const LoadLandPropertyAssessment());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -305,7 +305,7 @@ class _AddOtherImprovementModalOffline
|
|||
));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -324,7 +324,7 @@ class _AddOtherImprovementModalOffline
|
|||
.add(const LoadOtherImprovements());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -434,7 +434,8 @@ class _AddLandValueAdjustmentOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -457,7 +458,8 @@ class _AddLandValueAdjustmentOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -36,24 +36,30 @@ class _LandPropertyOwnerInfoOffline
|
|||
const SizedBox(height: 15),
|
||||
customDropDownField(
|
||||
"Transaction Code", "", "transaction_code", transaction_codes),
|
||||
customTextField("ARP No./ TD No.", "", "td_no"),
|
||||
customTextField("Owner", "", "owner"),
|
||||
customTextField(
|
||||
"ARP No./ TD No.", "", "td_no", TextInputType.number),
|
||||
customTextField("Owner", "", "owner", TextInputType.text),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(flex: 1, child: customTextField("PIN", "", "pin")),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"PIN", "", "pin", TextInputType.number)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", "tin"))
|
||||
child: customTextField(
|
||||
"TIN", "", "tin", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("OCT/TCT CLOA No.", "", "cloa_no"),
|
||||
child: customTextField("OCT/TCT CLOA No.", "", "cloa_no",
|
||||
TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -66,31 +72,21 @@ class _LandPropertyOwnerInfoOffline
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Survey No.", "", "survey_no"),
|
||||
child: customTextField(
|
||||
"Survey No.", "", "survey_no", TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Lot No.", "", "lot_no")),
|
||||
child: customTextField(
|
||||
"Lot No.", "", "lot_no", TextInputType.number)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Blk", "", "blk")),
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Address", "", "address"),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "", "tel_no"))
|
||||
child: customTextField(
|
||||
"Blk", "", "blk", TextInputType.number)),
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
|
@ -98,26 +94,44 @@ class _LandPropertyOwnerInfoOffline
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Administrator/Beneficial User", "", "admin"),
|
||||
"Address", "", "address", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", "admin_tin"))
|
||||
child: customTextField(
|
||||
"Tel No.", "", "tel_no", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Address", "", "admin_address"),
|
||||
child: customTextField("Administrator/Beneficial User", "",
|
||||
"admin", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "", "admin_telno"))
|
||||
child: customTextField(
|
||||
"TIN", "", "admin_tin", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Address", "", "admin_address", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Tel No.", "", "admin_telno", TextInputType.number))
|
||||
]),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
|
|
|
@ -57,14 +57,14 @@ class _LandLocationAndBoundariesOffline
|
|||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. / Street", "", "street")),
|
||||
child: customTextField("No. / Street", "",
|
||||
"street", TextInputType.text)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Brgy./District", "", "brgy")),
|
||||
child: customTextField("Brgy./District", "",
|
||||
"brgy", TextInputType.text)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
@ -72,15 +72,15 @@ class _LandLocationAndBoundariesOffline
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Municipality", "", "municipality"),
|
||||
child: customTextField("Municipality", "",
|
||||
"municipality", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Province/City", "", "province"))
|
||||
child: customTextField("Province/City", "",
|
||||
"province", TextInputType.text))
|
||||
]),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
|
@ -95,26 +95,30 @@ class _LandLocationAndBoundariesOffline
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("North", "", "north"),
|
||||
child: customTextField(
|
||||
"North", "", "north", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("East", "", "east"))
|
||||
child: customTextField(
|
||||
"East", "", "east", TextInputType.text))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("South", "", "south"),
|
||||
child: customTextField(
|
||||
"South", "", "south", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("West", "", "west"))
|
||||
child: customTextField(
|
||||
"West", "", "west", TextInputType.text))
|
||||
]),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
|
|
|
@ -343,7 +343,8 @@ class _AddLandAppraisalEditOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -366,7 +367,8 @@ class _AddLandAppraisalEditOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -302,7 +302,7 @@ class _AddOtherImprovementModalEditOffline
|
|||
));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -321,7 +321,7 @@ class _AddOtherImprovementModalEditOffline
|
|||
.add(const LoadOtherImprovements());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -290,7 +290,7 @@ class _AddPropertyAssessmentEditOfflineModal
|
|||
totalAssessedval: '0'));
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -310,7 +310,7 @@ class _AddPropertyAssessmentEditOfflineModal
|
|||
const LoadLandPropertyAssessment());
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -433,7 +433,8 @@ class _AddLandValueAdjustmentEditOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Submit"),
|
||||
),
|
||||
|
@ -456,7 +457,8 @@ class _AddLandValueAdjustmentEditOfflineModal
|
|||
},
|
||||
style:
|
||||
ElevatedButton.styleFrom(
|
||||
primary: Colors.black,
|
||||
backgroundColor:
|
||||
Colors.black,
|
||||
),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
|
|
|
@ -71,26 +71,30 @@ class _LandPropertyOwnerInfoOfflineEdit
|
|||
const SizedBox(height: 15),
|
||||
customDropDownField("Transaction Code", "",
|
||||
"transaction_code", transaction_codes),
|
||||
customTextField("ARP No./ TD No.", "", "td_no"),
|
||||
customTextField("Owner", "", "owner"),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1, child: customTextField("PIN", "", "pin")),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", "tin"))
|
||||
]),
|
||||
customTextField(
|
||||
"ARP No./ TD No.", "", "td_no", TextInputType.number),
|
||||
customTextField("Owner", "", "owner", TextInputType.text),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"OCT/TCT CLOA No.", "", "cloa_no"),
|
||||
"PIN", "", "pin", TextInputType.number)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"TIN", "", "tin", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("OCT/TCT CLOA No.", "",
|
||||
"cloa_no", TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
|
@ -103,31 +107,21 @@ class _LandPropertyOwnerInfoOfflineEdit
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Survey No.", "", "survey_no"),
|
||||
child: customTextField("Survey No.", "", "survey_no",
|
||||
TextInputType.number),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Lot No.", "", "lot_no")),
|
||||
child: customTextField(
|
||||
"Lot No.", "", "lot_no", TextInputType.number)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Blk", "", "blk")),
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Address", "", "address"),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "", "tel_no"))
|
||||
child: customTextField(
|
||||
"Blk", "", "blk", TextInputType.number)),
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
|
@ -135,28 +129,47 @@ class _LandPropertyOwnerInfoOfflineEdit
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Administrator/Beneficial User", "", "admin"),
|
||||
"Address", "", "address", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("TIN", "", "admin_tin"))
|
||||
child: customTextField(
|
||||
"Tel No.", "", "tel_no", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child:
|
||||
customTextField("Address", "", "admin_address"),
|
||||
child: customTextField(
|
||||
"Administrator/Beneficial User",
|
||||
"",
|
||||
"admin",
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child:
|
||||
customTextField("Tel No.", "", "admin_telno"))
|
||||
child: customTextField(
|
||||
"TIN", "", "admin_tin", TextInputType.number))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField("Address", "", "admin_address",
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField("Tel No.", "", "admin_telno",
|
||||
TextInputType.number))
|
||||
]),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
|
|
|
@ -96,14 +96,14 @@ class _LandLocationAndBoundariesOfflineEdit
|
|||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"No. / Street", "", "street")),
|
||||
child: customTextField("No. / Street",
|
||||
"", "street", TextInputType.text)),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Brgy./District", "", "brgy")),
|
||||
child: customTextField("Brgy./District",
|
||||
"", "brgy", TextInputType.text)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
|
@ -113,14 +113,20 @@ class _LandLocationAndBoundariesOfflineEdit
|
|||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Municipality", "", "municipality"),
|
||||
"Municipality",
|
||||
"",
|
||||
"municipality",
|
||||
TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"Province/City", "", "province"))
|
||||
"Province/City",
|
||||
"",
|
||||
"province",
|
||||
TextInputType.text))
|
||||
]),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
|
@ -137,15 +143,15 @@ class _LandLocationAndBoundariesOfflineEdit
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"North", "", "north"),
|
||||
child: customTextField("North", "",
|
||||
"north", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"East", "", "east"))
|
||||
child: customTextField("East", "",
|
||||
"east", TextInputType.text))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
|
@ -153,15 +159,15 @@ class _LandLocationAndBoundariesOfflineEdit
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"South", "", "south"),
|
||||
child: customTextField("South", "",
|
||||
"south", TextInputType.text),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
Expanded(
|
||||
// optional flex property if flex is 1 because the default flex is 1
|
||||
flex: 1,
|
||||
child: customTextField(
|
||||
"West", "", "west"))
|
||||
child: customTextField("West", "",
|
||||
"west", TextInputType.text))
|
||||
]),
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
|
|
|
@ -19,7 +19,7 @@ class PassoOfflineMainScreen extends StatelessWidget {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: primary,
|
||||
title: const Text("PASSO Offlne Home"),
|
||||
title: const Text("Rpass Offline Home"),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: Padding(
|
||||
|
@ -50,15 +50,6 @@ class PassoOfflineMainScreen extends StatelessWidget {
|
|||
return PassoOfflineDashBoard(offlineProfile);
|
||||
})));
|
||||
}),
|
||||
CardLabel(
|
||||
icon: FontAwesome5.tools,
|
||||
title: "Super Admin",
|
||||
ontap: () {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: ((context) {
|
||||
return PassoOfflineDashBoard(offlineProfile);
|
||||
})));
|
||||
})
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class AddMobile extends StatelessWidget {
|
|||
),
|
||||
Text(addMobileCaption,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.caption),
|
||||
style: Theme.of(context).textTheme.bodyMedium),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
|
@ -81,16 +81,16 @@ class AddMobile extends StatelessWidget {
|
|||
name: 'mobile1',
|
||||
validator: mobileNumberValidator,
|
||||
maxLength: 11,
|
||||
decoration:
|
||||
normalTextFieldStyle(mobile1, "sfdfsdfsd")),
|
||||
decoration: normalTextFieldStyle(
|
||||
mobile1, "sfdfsdfsd")),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
name: 'mobile2',
|
||||
maxLength: 11,
|
||||
decoration:
|
||||
normalTextFieldStyle(mobile2, "0900000000000")),
|
||||
decoration: normalTextFieldStyle(
|
||||
mobile2, "0900000000000")),
|
||||
|
||||
SizedBox(
|
||||
height: isMobile()
|
||||
|
@ -108,9 +108,7 @@ class AddMobile extends StatelessWidget {
|
|||
),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!
|
||||
.saveAndValidate()) {
|
||||
|
||||
}
|
||||
.saveAndValidate()) {}
|
||||
|
||||
// }
|
||||
},
|
||||
|
|
|
@ -11,11 +11,11 @@ import '../../../utils/global.dart';
|
|||
class SosAcknowledged extends StatelessWidget {
|
||||
final Function() onpressed;
|
||||
final SessionData sessionData;
|
||||
const SosAcknowledged({super.key, required this.onpressed, required this.sessionData});
|
||||
const SosAcknowledged(
|
||||
{super.key, required this.onpressed, required this.sessionData});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 35),
|
||||
height: screenHeight,
|
||||
|
@ -71,13 +71,14 @@ class SosAcknowledged extends StatelessWidget {
|
|||
borderRadius: BorderRadius.all(Radius.circular(15))),
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
|
||||
ListTile(
|
||||
title: AutoSizeText(
|
||||
sessionData.acknowledgedBy!.toUpperCase(),
|
||||
maxLines: 2,
|
||||
style: Theme.of(context).textTheme.headline4!.copyWith(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineMedium!
|
||||
.copyWith(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: third),
|
||||
|
@ -92,7 +93,8 @@ class SosAcknowledged extends StatelessWidget {
|
|||
child: Text(
|
||||
"NOTE: Please ensure that the mobile numbers you provided are still active, and look for an area with stable network. The response team will contact your mobile number.",
|
||||
textAlign: TextAlign.justify,
|
||||
style: Theme.of(context).textTheme.caption!.copyWith(
|
||||
style:
|
||||
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
|
@ -108,8 +110,8 @@ class SosAcknowledged extends StatelessWidget {
|
|||
height: 50,
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
style:
|
||||
mainBtnStyle(second, Colors.transparent, Colors.white54),
|
||||
style: mainBtnStyle(
|
||||
second, Colors.transparent, Colors.white54),
|
||||
onPressed: onpressed,
|
||||
child: const Text("DONE!")),
|
||||
),
|
||||
|
|
|
@ -24,7 +24,7 @@ class Mobile extends StatelessWidget {
|
|||
title: Text(title),
|
||||
subtitle: Text(
|
||||
subtitle,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.edit),
|
||||
|
|
|
@ -14,7 +14,6 @@ class SOSreceived extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 35),
|
||||
height: screenHeight,
|
||||
|
@ -99,7 +98,7 @@ class SOSreceived extends StatelessWidget {
|
|||
child: AutoSizeText(
|
||||
sOSReceivedMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.caption!.copyWith(
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 16,
|
||||
color: Colors.black87,
|
||||
),
|
||||
|
|
|
@ -43,7 +43,7 @@ class NoModule extends StatelessWidget {
|
|||
noModuleSubTitle,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.caption!
|
||||
.bodySmall!
|
||||
.copyWith(fontSize: blockSizeVertical * 1.5),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
|
|
|
@ -5,7 +5,8 @@ import '../../../../../theme-data.dart/colors.dart';
|
|||
class SelectedState extends StatelessWidget {
|
||||
final String title;
|
||||
final String subtitle;
|
||||
const SelectedState({Key? key,required this.subtitle, required this.title}) : super(key: key);
|
||||
const SelectedState({Key? key, required this.subtitle, required this.title})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -24,7 +25,7 @@ class SelectedState extends StatelessWidget {
|
|||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.button!.copyWith(
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||
color: third, fontWeight: FontWeight.bold, fontSize: 18),
|
||||
),
|
||||
Text(
|
||||
|
@ -32,7 +33,6 @@ class SelectedState extends StatelessWidget {
|
|||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
]),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -82,7 +82,7 @@ class _ViewListState extends State<ViewList> {
|
|||
dense: true,
|
||||
subtitle: Text(
|
||||
"December 15 1994",
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
leading: Checkbox(
|
||||
onChanged: (value) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import '../../../../../model/passo/additional_items.dart';
|
|||
import '../../../../../model/passo/barangay.dart';
|
||||
import '../../../../../model/passo/building_and_structure.dart';
|
||||
import '../../../../../model/passo/class_components _offline.dart';
|
||||
import '../../../../../model/passo/floor_sketch.dart';
|
||||
import '../../../../../model/passo/general_description.dart';
|
||||
import '../../../../../model/passo/land_appr.dart';
|
||||
import '../../../../../model/passo/land_classification.dart';
|
||||
|
@ -178,6 +179,16 @@ class SQLServices {
|
|||
)
|
||||
''');
|
||||
|
||||
await db.execute('''
|
||||
CREATE TABLE bldg_floor_sketch (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
bldgappr_details_id INTEGER NOT NULL,
|
||||
date_created TEXT NOT NULL,
|
||||
floor_sketch TEXT NOT NULL,
|
||||
gen_code TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
|
||||
await db.execute('''
|
||||
CREATE TABLE value_adjustments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
|
@ -213,7 +224,8 @@ class SQLServices {
|
|||
assessedByName TEXT NOT NULL,
|
||||
dateCreated TEXT NOT NULL,
|
||||
dateModified TEXT NOT NULL,
|
||||
gen_code TEXT
|
||||
gen_code TEXT,
|
||||
dateSynced TEXT
|
||||
)
|
||||
''');
|
||||
|
||||
|
@ -303,7 +315,8 @@ class SQLServices {
|
|||
marketValue TEXT NOT NULL,
|
||||
depAmount TEXT NOT NULL,
|
||||
adjustedMarketValue TEXT NOT NULL,
|
||||
gen_code TEXT
|
||||
gen_code TEXT,
|
||||
dateSync TEXT
|
||||
)
|
||||
''');
|
||||
|
||||
|
@ -403,7 +416,8 @@ class SQLServices {
|
|||
paintedUnitval TEXT NOT NULL,
|
||||
secondhandUnitval TEXT NOT NULL,
|
||||
actualUse TEXT NOT NULL,
|
||||
gen_code TEXT
|
||||
gen_code TEXT,
|
||||
dateSync TEXT
|
||||
)
|
||||
''');
|
||||
|
||||
|
@ -932,6 +946,7 @@ class SQLServices {
|
|||
"assessedByName": propertyInfo.assessedByName,
|
||||
"dateCreated": "000",
|
||||
"dateModified": "000",
|
||||
"dateSynced": propertyInfo.dateSynced
|
||||
};
|
||||
|
||||
final result =
|
||||
|
@ -1179,6 +1194,32 @@ class SQLServices {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Floor Sketch
|
||||
|
||||
Future<FloorSketch> createFloorSketch(FloorSketch floorSketch) async {
|
||||
final db = await instance.database;
|
||||
|
||||
final data = {
|
||||
// "id": treesImprovements.id,
|
||||
"bldgappr_details_id": floorSketch.bldgapprDetailsId,
|
||||
"date_created": floorSketch.dateCreated,
|
||||
"floor_sketch": floorSketch.floorSketch,
|
||||
"gen_code": "5TH"
|
||||
};
|
||||
final id = await db.insert('bldg_floor_sketch', data);
|
||||
return floorSketch.copy(bldgapprDetailsId: id);
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> getFloorSketch(id) async {
|
||||
final db = await instance.database;
|
||||
final results = await db.query('bldg_floor_sketch',
|
||||
where: "bldgappr_details_id = ?", whereArgs: [id], limit: 1);
|
||||
print('floor sketch test result');
|
||||
print(results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
//Structural Materials
|
||||
|
||||
Future<StructureMaterialsII> createStructuralMaterials(
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:unit2/theme-data.dart/btn-style.dart';
|
|||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
||||
confirmAlert(context, Function() yes,String title, String subtitle) {
|
||||
confirmAlert(context, Function() yes, String title, String subtitle) {
|
||||
AwesomeDialog(
|
||||
context: context,
|
||||
dialogType: DialogType.question,
|
||||
|
@ -37,7 +37,13 @@ confirmAlert(context, Function() yes,String title, String subtitle) {
|
|||
).show();
|
||||
}
|
||||
|
||||
confirmAlertWithCancel(context, Function() yes,Function() no,String title, String subtitle,) {
|
||||
confirmAlertWithCancel(
|
||||
context,
|
||||
Function() yes,
|
||||
Function() no,
|
||||
String title,
|
||||
String subtitle,
|
||||
) {
|
||||
AwesomeDialog(
|
||||
context: context,
|
||||
dialogType: DialogType.question,
|
||||
|
@ -70,8 +76,41 @@ confirmAlertWithCancel(context, Function() yes,Function() no,String title, Strin
|
|||
).show();
|
||||
}
|
||||
|
||||
confirmAlertWithCancelCustom(context, Function() yes, Function() no,
|
||||
String title, String subtitle, okText, cancelText) {
|
||||
AwesomeDialog(
|
||||
context: context,
|
||||
dialogType: DialogType.question,
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.green,
|
||||
width: 0,
|
||||
),
|
||||
width: blockSizeHorizontal * 90,
|
||||
buttonsBorderRadius: const BorderRadius.all(
|
||||
Radius.circular(2),
|
||||
),
|
||||
dismissOnTouchOutside: false,
|
||||
dismissOnBackKeyPress: false,
|
||||
// onDismissCallback: (type) {
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text('Dismissed by $type'),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
headerAnimationLoop: false,
|
||||
animType: AnimType.bottomSlide,
|
||||
title: title,
|
||||
desc: subtitle,
|
||||
btnOkText: okText,
|
||||
btnCancelText: cancelText,
|
||||
showCloseIcon: false,
|
||||
btnCancelOnPress: no,
|
||||
btnOkOnPress: yes,
|
||||
).show();
|
||||
}
|
||||
|
||||
errorAlert(context, title, description,Function() func) {
|
||||
errorAlert(context, title, description, Function() func) {
|
||||
AwesomeDialog(
|
||||
width: blockSizeHorizontal * 90,
|
||||
context: context,
|
||||
|
@ -80,10 +119,16 @@ errorAlert(context, title, description,Function() func) {
|
|||
headerAnimationLoop: false,
|
||||
title: title,
|
||||
desc: description,
|
||||
btnOk: SizedBox(height: 50,child: ElevatedButton(onPressed:func, style: mainBtnStyle(primary, Colors.transparent, second), child: const Text("OK")), )
|
||||
).show();
|
||||
btnOk: SizedBox(
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
onPressed: func,
|
||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
||||
child: const Text("OK")),
|
||||
)).show();
|
||||
}
|
||||
successAlert(context, title, description,Function() func) {
|
||||
|
||||
successAlert(context, title, description, Function() func) {
|
||||
AwesomeDialog(
|
||||
width: blockSizeHorizontal * 90,
|
||||
context: context,
|
||||
|
@ -92,10 +137,16 @@ successAlert(context, title, description,Function() func) {
|
|||
headerAnimationLoop: false,
|
||||
title: title,
|
||||
desc: description,
|
||||
btnOk: SizedBox(height: 50,child: ElevatedButton(style: mainBtnStyle(success2, Colors.transparent, success), onPressed: func, child: const Text("OK")), )
|
||||
).show();
|
||||
btnOk: SizedBox(
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(success2, Colors.transparent, success),
|
||||
onPressed: func,
|
||||
child: const Text("OK")),
|
||||
)).show();
|
||||
}
|
||||
okAlert(context,title,description){
|
||||
|
||||
okAlert(context, title, description) {
|
||||
AwesomeDialog(
|
||||
width: blockSizeHorizontal * 90,
|
||||
context: context,
|
||||
|
|
|
@ -5,7 +5,7 @@ class Url {
|
|||
|
||||
String host() {
|
||||
// // // return '192.168.10.183:3000';
|
||||
return 'agusandelnorte.gov.ph';
|
||||
// return 'agusandelnorte.gov.ph';
|
||||
// return "192.168.10.219:3000";
|
||||
// return "192.168.10.241";
|
||||
// return "192.168.10.185";
|
||||
|
@ -16,7 +16,7 @@ class Url {
|
|||
// return "192.168.10.247";
|
||||
// return "playcensys.agusandelnorte.gov.ph";
|
||||
// return "10.10.10.110:8000";
|
||||
// return "192.168.80.20:8000";
|
||||
return "192.168.80.20:8000";
|
||||
}
|
||||
|
||||
String prefixHost() {
|
||||
|
|
|
@ -3,11 +3,13 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
|
||||
Widget customTextField(String labelText, String hintText, String keyText) {
|
||||
Widget customTextField(
|
||||
String labelText, String hintText, String keyText, TextInputType type) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 0, top: 10, right: 0, bottom: 0),
|
||||
child: FormBuilderTextField(
|
||||
name: keyText,
|
||||
keyboardType: type,
|
||||
decoration: normalTextFieldStyle(labelText, hintText),
|
||||
validator: FormBuilderValidators.compose([]),
|
||||
),
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <modal_progress_hud_nsn/modal_progress_hud_nsn_plugin.h>
|
||||
#include <platform_device_id_linux/platform_device_id_linux_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
@ -15,6 +16,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) modal_progress_hud_nsn_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ModalProgressHudNsnPlugin");
|
||||
modal_progress_hud_nsn_plugin_register_with_registrar(modal_progress_hud_nsn_registrar);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_linux
|
||||
file_selector_linux
|
||||
modal_progress_hud_nsn
|
||||
platform_device_id_linux
|
||||
url_launcher_linux
|
||||
|
|
|
@ -9,6 +9,7 @@ import assets_audio_player
|
|||
import assets_audio_player_web
|
||||
import audioplayers_darwin
|
||||
import device_info_plus
|
||||
import file_selector_macos
|
||||
import location
|
||||
import modal_progress_hud_nsn
|
||||
import package_info_plus
|
||||
|
@ -27,6 +28,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
AssetsAudioPlayerWebPlugin.register(with: registry.registrar(forPlugin: "AssetsAudioPlayerWebPlugin"))
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
|
||||
ModalProgressHudNsnPlugin.register(with: registry.registrar(forPlugin: "ModalProgressHudNsnPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
|
|
134
pubspec.lock
134
pubspec.lock
|
@ -330,7 +330,7 @@ packages:
|
|||
source: hosted
|
||||
version: "4.7.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: collection
|
||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||
|
@ -513,6 +513,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_linux
|
||||
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.2+1"
|
||||
file_selector_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_macos
|
||||
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+1"
|
||||
file_utils:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -582,6 +614,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.3"
|
||||
flutter_drawing_board:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_drawing_board
|
||||
sha256: "82700847d7f367c9af1eaf186c88f74a6be821dbe783871e4736bf724f015192"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0+2"
|
||||
flutter_form_builder:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -603,6 +643,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_painter_v2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_painter_v2
|
||||
sha256: "5f9589670fb2385b69daf60ad1919c4f2b9ae2c5ee5199c0172c674032020470"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -813,6 +861,70 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.3"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker
|
||||
sha256: "1f498d086203360cca099d20ffea2963f48c39ce91bdd8a3b6d4a045786b02c8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
image_picker_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "42c098e7fb6334746be37cdc30369ade356ed4f14d48b7a0313f95a9159f4321"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.9+5"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_for_web
|
||||
sha256: e2423c53a68b579a7c37a1eda967b8ae536c3d98518e5db95ca1fe5719a730a3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
image_picker_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_ios
|
||||
sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.9+1"
|
||||
image_picker_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_linux
|
||||
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
image_picker_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_macos
|
||||
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
sha256: "0e827c156e3a90edd3bbe7f6de048b39247b16e58173b08a835b7eb00aba239e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.2"
|
||||
image_picker_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_windows
|
||||
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -902,7 +1014,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.5.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
|
@ -910,7 +1022,7 @@ packages:
|
|||
source: hosted
|
||||
version: "0.12.16"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
|
@ -918,7 +1030,7 @@ packages:
|
|||
source: hosted
|
||||
version: "0.5.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: meta
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
|
@ -1022,7 +1134,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
|
@ -1133,6 +1245,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.0"
|
||||
phosphor_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: phosphor_flutter
|
||||
sha256: "82aee69109d55518abbc5d77aeb893bfd2d39796aa51b871cadf2e56d03fa8e3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1475,7 +1595,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.5.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||
|
@ -1491,7 +1611,7 @@ packages:
|
|||
source: hosted
|
||||
version: "6.3.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||
|
|
12
pubspec.yaml
12
pubspec.yaml
|
@ -100,10 +100,20 @@ dependencies:
|
|||
sqflite: ^2.3.0
|
||||
accordion: ^2.6.0
|
||||
dropdown_button2: ^2.3.9
|
||||
|
||||
phosphor_flutter: ^1.4.0
|
||||
device_info_plus: ^9.0.3
|
||||
better_open_file: ^3.6.4
|
||||
date_format: ^2.0.7
|
||||
flutter_drawing_board: ^0.7.0+2
|
||||
flutter_painter_v2: ^2.0.1
|
||||
image_picker: ^1.0.8
|
||||
collection: ^1.17.2
|
||||
matcher: ^0.12.16
|
||||
material_color_utilities: ^0.5.0
|
||||
meta: ^1.9.1
|
||||
path: ^1.8.3
|
||||
stack_trace: ^1.11.0
|
||||
stream_channel: ^2.1.1
|
||||
dependency_overrides:
|
||||
intl: ^0.18.0
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <modal_progress_hud_nsn/modal_progress_hud_nsn_plugin_c_api.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <platform_device_id_windows/platform_device_id_windows_plugin.h>
|
||||
|
@ -18,6 +19,8 @@
|
|||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
ModalProgressHudNsnPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ModalProgressHudNsnPluginCApi"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_windows
|
||||
file_selector_windows
|
||||
modal_progress_hud_nsn
|
||||
permission_handler_windows
|
||||
platform_device_id_windows
|
||||
|
|
Loading…
Reference in New Issue