added drawing pad

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
cyzoox 2024-07-11 09:27:35 +08:00
parent 593041b19b
commit 9f0cc75a3f
72 changed files with 7264 additions and 3998 deletions

View File

@ -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()

View File

@ -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

View File

@ -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,297 +88,417 @@ class CrudBloc extends Bloc<CrudEvent, CrudState> {
on<DeleteTodo>((event, emit) async {
await SQLServices.instance.deleteBldgOwner(id: event.id);
add(const FetchTodos());
// Directly fetch and emit new data rather than triggering another event
try {
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());
}
});
on<UploadBuildingFaas>(((event, emit) async {
Future<Map<String, dynamic>> _prepareBuildingDetails(
UploadBuildingFaas event, PropertyInfo infos) async {
// Fetch data
List<Map<String, dynamic>> genDesc =
await SQLServices.instance.getGeneralDescription(infos.id);
List<Map<String, dynamic>> loc =
await SQLServices.instance.getLocation(infos.id);
List<Map<String, dynamic>> landRef =
await SQLServices.instance.getLandRef(infos.id);
List<Map<String, dynamic>> assessment =
await SQLServices.instance.getBldgAssessment(infos.id);
List<Map<String, dynamic>> strucMat =
await SQLServices.instance.getStructuralMaterials(infos.id);
List<Map<String, dynamic>> addItems =
await SQLServices.instance.getAdditionalItems(infos.id);
List<Map<String, dynamic>> bldgStructure =
await SQLServices.instance.getBuildingAndStructure(infos.id);
// 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": '08887',
"tdn": infos.tdn,
"pin": infos.pin,
"fname": infos.fname,
"mname": infos.mname,
"lname": infos.lname,
"bday": infos.bday,
"address": infos.address,
"telno": infos.telno,
"tin": infos.tin,
"admin_user": infos.adminUser,
"admin_address": infos.adminAddress,
"admin_telno": infos.adminTelno,
"admin_tin": infos.adminTin,
"faas_type": infos.faasType,
"gen_code": "5TH",
"bldgappr_location.date_created": "{{currentTimestamp}}",
"bldgappr_location.date_modified": "{{currentTimestamp}}",
"bldgappr_location.street": firstLoc.street,
"bldgappr_location.barangay": firstLoc.barangay,
"bldgappr_location.municipality": firstLoc.municipality,
"bldgappr_location.province": firstLoc.province,
"bldgappr_location.gen_code": "5TH",
"bldgappr_landref.date_created": "{{currentTimestamp}}",
"bldgappr_landref.date_modified": "{{currentTimestamp}}",
"bldgappr_landref.owner": firstLandRef.owner,
"bldgappr_landref.cloa_no": firstLandRef.cloaNo,
"bldgappr_landref.lot_no": firstLandRef.lotNo,
"bldgappr_landref.tdn": firstLandRef.tdn,
"bldgappr_landref.area": firstLandRef.area,
"bldgappr_landref.survey_no": firstLandRef.surveyNo,
"bldgappr_landref.blk_no": firstLandRef.blkNo,
"bldgappr_landref.gen_code": "5TH",
"bldgappr_generaldesc.date_created": "{{currentTimestamp}}",
"bldgappr_generaldesc.date_modified": "{{currentTimestamp}}",
"bldgappr_generaldesc.bldg_kind": firstGenDesc.bldgKind,
"bldgappr_generaldesc.struc_type": firstGenDesc.strucType,
"bldgappr_generaldesc.bldg_permit": firstGenDesc.bldgPermit,
"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")
.format(DateTime.parse(firstGenDesc.certCompletionIssued!)),
"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!)),
"bldgappr_generaldesc.date_occupied": DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstGenDesc.dateOccupied!)),
"bldgappr_generaldesc.bldg_age": firstGenDesc.bldgAge,
"bldgappr_generaldesc.no_storeys": firstGenDesc.noStoreys,
"bldgappr_generaldesc.area_1stfloor": firstGenDesc.area1Stfloor,
"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.floor_sketch": null,
"bldgappr_generaldesc.actual_use": firstGenDesc.actualUse,
"bldgappr_generaldesc.unit_value": firstGenDesc.unitValue,
"bldgappr_generaldesc.gen_code": "5TH",
"bldgappr_struct_materials.date_created": "{{currentTimestamp}}",
"bldgappr_struct_materials.date_modified": "{{currentTimestamp}}",
"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.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.actual_use": firstAssess.actualUse,
"bldgappr_property_assessment.market_value": firstAssess.marketValue,
"bldgappr_property_assessment.assessment_level":
firstAssess.assessmentLevel,
"bldgappr_property_assessment.assessed_value":
firstAssess.assessedValue,
"bldgappr_property_assessment.taxable": firstAssess.taxable,
"bldgappr_property_assessment.exempt": firstAssess.exempt,
"bldgappr_property_assessment.qtr": firstAssess.qtr,
"bldgappr_property_assessment.yr": firstAssess.yr,
"bldgappr_property_assessment.appraisedby_name":
firstAssess.appraisedbyName,
"bldgappr_property_assessment.appraisedby_designation":
firstAssess.appraisedbyDesignation,
"bldgappr_property_assessment.appraisedby_date":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.appraisedbyDate!)),
"bldgappr_property_assessment.recommendappr_name":
firstAssess.recommendapprName,
"bldgappr_property_assessment.recommendappr_designation":
firstAssess.recommendapprDesignation,
"bldgappr_property_assessment.recommendappr_date":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.recommendapprDate!)),
"bldgappr_property_assessment.approvedby_name":
firstAssess.approvedbyName,
"bldgappr_property_assessment.approvedby_designation":
firstAssess.approvedbyDesignation,
"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")
.format(DateTime.parse(firstAssess.dateReceived!)),
"bldgappr_property_assessment.entry_date_assessment":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.entryDateAssessment!)),
"bldgappr_property_assessment.entry_date_by": " ",
"bldgappr_property_assessment.gen_code": "5TH",
"bldgappr_rec_supersededass.date_created": "{{currentTimestamp}}",
"bldgappr_rec_supersededass.date_modified": "{{currentTimestamp}}",
"bldgappr_rec_supersededass.pin": " ",
"bldgappr_rec_supersededass.tdn": " ",
"bldgappr_rec_supersededass.total_assval": "0",
"bldgappr_rec_supersededass.owner": " ",
"bldgappr_rec_supersededass.effectivity_ass": null,
"bldgappr_rec_supersededass.page_no": "0",
"bldgappr_rec_supersededass.total_marketval": "0",
"bldgappr_rec_supersededass.total_area": "0",
"bldgappr_rec_supersededass.rec_assessment": null,
"bldgappr_rec_supersededass.rec_taxmapping": " ",
"bldgappr_rec_supersededass.rec_records": " ",
"bldgappr_rec_supersededass.date": null,
"bldgappr_rec_supersededass.gen_code": "5TH"
};
return details;
}
Future<void> _postAdditionalItems(
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>> addItems =
await SQLServices.instance.getAdditionalItems(infos.id);
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'],
classId: items.classId,
className: items.className,
structType: items.structType,
unitValue: items.unitValue,
baseUnitValue: items.baseUnitValue,
area: items.area,
marketValue: items.marketValue,
depreciationRate: items.depreciationRate,
adjustedMarketVal: items.adjustedMarketVal,
amtDepreciation: items.amtDepreciation,
painted: items.painted,
secondhand: items.secondhand,
paintedUnitval: items.paintedUnitval,
secondhandUnitval: items.secondhandUnitval,
actualUse: items.actualUse,
genCode: "5TH");
Response addResponse = await post(
Uri.parse(
'http://${Url.instance.host()}/api/rptass_app/additional_items/'),
headers: headers,
body: jsonEncode(addItems));
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,
bldgapprDetailsId: datas['data']['id'],
bldgArea: structure.bldgArea,
bldgType: structure.bldgType,
structType: structure.structType,
description: structure.description,
actualUse: structure.actualUse,
floorCount: structure.floorCount,
unitValue: structure.unitValue,
depRate: structure.depRate,
marketValue: structure.marketValue,
depAmount: structure.depAmount,
adjustedMarketValue: structure.adjustedMarketValue,
genCode: '5TH',
buccPercentage: structure.buccPercentage);
Response response = await post(
Uri.parse(
'http://${Url.instance.host()}/api/rptass_app/bldgappr_structure/'),
headers: headers,
body: jsonEncode(bldgStruc));
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) {
//General Description
List<Map<String, dynamic>> genDesc =
await SQLServices.instance.getGeneralDescription(infos.id);
List<GeneralDesc> genDescList =
genDesc.map((map) => GeneralDesc.fromJson2(map)).toList();
final details = await _prepareBuildingDetails(event, infos);
GeneralDesc firstGenDesc = genDescList.first;
Response detailsResponse = await _postBuildingDetails(details);
final datas = json.decode(detailsResponse.body);
//Location
List<Map<String, dynamic>> loc =
await SQLServices.instance.getLocation(infos.id);
print(datas);
List<BldgLoc> locList =
loc.map((map) => BldgLoc.fromJson2(map)).toList();
await _postAdditionalItems(datas, infos);
await _postBuildingStructures(datas, infos);
await _uploadImage(datas, infos);
BldgLoc firstLoc = locList.first;
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()));
//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();
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',
"pin": infos.pin,
"fname": infos.fname,
"mname": infos.mname,
"lname": infos.lname,
"bday": infos.bday,
"address": infos.address,
"telno": infos.telno,
"tin": infos.tin,
"admin_user": infos.adminUser,
"admin_address": infos.adminAddress,
"admin_telno": infos.adminTelno,
"admin_tin": infos.adminTin,
"faas_type": infos.faasType,
"gen_code": "5TH",
"bldgappr_location.date_created": "{{currentTimestamp}}",
"bldgappr_location.date_modified": "{{currentTimestamp}}",
"bldgappr_location.street": firstLoc.street,
"bldgappr_location.barangay": firstLoc.barangay,
"bldgappr_location.municipality": firstLoc.municipality,
"bldgappr_location.province": firstLoc.province,
"bldgappr_location.gen_code": "5TH",
"bldgappr_landref.date_created": "{{currentTimestamp}}",
"bldgappr_landref.date_modified": "{{currentTimestamp}}",
"bldgappr_landref.owner": firstLandRef.owner,
"bldgappr_landref.cloa_no": firstLandRef.cloaNo,
"bldgappr_landref.lot_no": firstLandRef.lotNo,
"bldgappr_landref.tdn": firstLandRef.tdn,
"bldgappr_landref.area": firstLandRef.area,
"bldgappr_landref.survey_no": firstLandRef.surveyNo,
"bldgappr_landref.blk_no": firstLandRef.blkNo,
"bldgappr_landref.gen_code": "5TH",
"bldgappr_generaldesc.date_created": "{{currentTimestamp}}",
"bldgappr_generaldesc.date_modified": "{{currentTimestamp}}",
"bldgappr_generaldesc.bldg_kind": firstGenDesc.bldgKind,
"bldgappr_generaldesc.struc_type": firstGenDesc.strucType,
"bldgappr_generaldesc.bldg_permit": firstGenDesc.bldgPermit,
"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")
.format(DateTime.parse(firstGenDesc.certCompletionIssued!)),
"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!)),
"bldgappr_generaldesc.date_occupied": DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstGenDesc.dateOccupied!)),
"bldgappr_generaldesc.bldg_age": firstGenDesc.bldgAge,
"bldgappr_generaldesc.no_storeys": firstGenDesc.noStoreys,
"bldgappr_generaldesc.area_1stfloor": firstGenDesc.area1Stfloor,
"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.floor_sketch": null,
"bldgappr_generaldesc.actual_use": firstGenDesc.actualUse,
"bldgappr_generaldesc.unit_value": firstGenDesc.unitValue,
"bldgappr_generaldesc.gen_code": "5TH",
"bldgappr_struct_materials.date_created": "{{currentTimestamp}}",
"bldgappr_struct_materials.date_modified": "{{currentTimestamp}}",
"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.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.actual_use": firstAssess.actualUse,
"bldgappr_property_assessment.market_value":
firstAssess.marketValue,
"bldgappr_property_assessment.assessment_level":
firstAssess.assessmentLevel,
"bldgappr_property_assessment.assessed_value":
firstAssess.assessedValue,
"bldgappr_property_assessment.taxable": firstAssess.taxable,
"bldgappr_property_assessment.exempt": firstAssess.exempt,
"bldgappr_property_assessment.qtr": firstAssess.qtr,
"bldgappr_property_assessment.yr": firstAssess.yr,
"bldgappr_property_assessment.appraisedby_name":
firstAssess.appraisedbyName,
"bldgappr_property_assessment.appraisedby_designation":
firstAssess.appraisedbyDesignation,
"bldgappr_property_assessment.appraisedby_date":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.appraisedbyDate!)),
"bldgappr_property_assessment.recommendappr_name":
firstAssess.recommendapprName,
"bldgappr_property_assessment.recommendappr_designation":
firstAssess.recommendapprDesignation,
"bldgappr_property_assessment.recommendappr_date":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.recommendapprDate!)),
"bldgappr_property_assessment.approvedby_name":
firstAssess.approvedbyName,
"bldgappr_property_assessment.approvedby_designation":
firstAssess.approvedbyDesignation,
"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")
.format(DateTime.parse(firstAssess.dateReceived!)),
"bldgappr_property_assessment.entry_date_assessment":
DateFormat("yyyy-MM-dd")
.format(DateTime.parse(firstAssess.entryDateAssessment!)),
"bldgappr_property_assessment.entry_date_by": " ",
"bldgappr_property_assessment.gen_code": "5TH",
"bldgappr_rec_supersededass.date_created": "{{currentTimestamp}}",
"bldgappr_rec_supersededass.date_modified": "{{currentTimestamp}}",
"bldgappr_rec_supersededass.pin": " ",
"bldgappr_rec_supersededass.tdn": " ",
"bldgappr_rec_supersededass.total_assval": "0",
"bldgappr_rec_supersededass.owner": " ",
"bldgappr_rec_supersededass.effectivity_ass": null,
"bldgappr_rec_supersededass.page_no": "0",
"bldgappr_rec_supersededass.total_marketval": "0",
"bldgappr_rec_supersededass.total_area": "0",
"bldgappr_rec_supersededass.rec_assessment": null,
"bldgappr_rec_supersededass.rec_taxmapping": " ",
"bldgappr_rec_supersededass.rec_records": " ",
"bldgappr_rec_supersededass.date": null,
"bldgappr_rec_supersededass.gen_code": "5TH"
};
// http.Response response =
// (await BuildingServices.instance.add(details))!;
// print(response.body);
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
};
Response details_response = await post(
Uri.parse(
'https://${Url.instance.host()}/api/rptass_app/bldgappr_details/'),
headers: headers,
body: jsonEncode(details));
final datas = json.decode(details_response.body);
for (AdditionalItems items in addItemsList) {
final addItems = AdditionalItems(
id: 1,
bldgapprDetailsId: datas['data']['id'],
classId: items.classId,
className: items.className,
structType: items.structType,
unitValue: items.unitValue,
baseUnitValue: items.baseUnitValue,
area: items.area,
marketValue: items.marketValue,
depreciationRate: items.depreciationRate,
adjustedMarketVal: items.adjustedMarketVal,
amtDepreciation: items.amtDepreciation,
painted: items.painted,
secondhand: items.secondhand,
paintedUnitval: items.paintedUnitval,
secondhandUnitval: items.secondhandUnitval,
actualUse: items.actualUse,
genCode: "5TH");
Response add_response = await post(
Uri.parse(
'https://${Url.instance.host()}/api/rptass_app/additional_items/'),
headers: headers,
body: jsonEncode(addItems));
print('add_response.body');
print(add_response.body);
}
for (BldgAndStructure structure in bldgStructureList) {
final bldgStruc = BldgAndStructure(
id: 1,
bldgapprDetailsId: datas['data']['id'],
bldgArea: structure.bldgArea,
bldgType: structure.bldgType,
structType: structure.structType,
description: structure.description,
actualUse: structure.actualUse,
floorCount: structure.floorCount,
unitValue: structure.unitValue,
depRate: structure.depRate,
marketValue: structure.marketValue,
depAmount: structure.depAmount,
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/'),
headers: headers,
body: jsonEncode(bldgStruc));
print('response.body');
print(response.body);
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()));
}
}));
;
});
}
}

View File

@ -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());
});

View File

@ -2,7 +2,6 @@
//
// final additionalItems = additionalItemsFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
AdditionalItems additionalItemsFromJson(String str) =>

View File

@ -2,7 +2,6 @@
//
// final classComponents = classComponentsFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
ClassComponentsOffline classComponentsFromJson(String str) =>

View File

@ -2,7 +2,6 @@
//
// final classComponents = classComponentsFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert';
ClassComponents classComponentsFromJson(String str) =>

View File

@ -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,
};
}

View File

@ -31,131 +31,131 @@ class PropertyInfo {
final String? adminTin;
final String? faasType;
final String? genCode;
final String? dateSynced;
PropertyInfo({
this.id,
this.assessedById,
this.assessedByName,
this.dateCreated,
this.dateModified,
this.transCode,
this.tdn,
this.pin,
this.fname,
this.mname,
this.lname,
this.bday,
this.address,
this.telno,
this.tin,
this.adminUser,
this.adminAddress,
this.adminTelno,
this.adminTin,
this.faasType,
this.genCode,
});
PropertyInfo(
{this.id,
this.assessedById,
this.assessedByName,
this.dateCreated,
this.dateModified,
this.transCode,
this.tdn,
this.pin,
this.fname,
this.mname,
this.lname,
this.bday,
this.address,
this.telno,
this.tin,
this.adminUser,
this.adminAddress,
this.adminTelno,
this.adminTin,
this.faasType,
this.genCode,
this.dateSynced});
PropertyInfo copy({
int? id,
String? assessedById,
String? assessedByName,
String? dateCreated,
String? dateModified,
String? transCode,
String? tdn,
String? pin,
String? owner,
String? address,
String? telno,
String? tin,
String? adminUser,
String? adminAddress,
String? adminTelno,
String? adminTin,
String? faasType,
String? genCode,
}) =>
PropertyInfo copy(
{int? id,
String? assessedById,
String? assessedByName,
String? dateCreated,
String? dateModified,
String? transCode,
String? tdn,
String? pin,
String? owner,
String? address,
String? telno,
String? tin,
String? adminUser,
String? adminAddress,
String? adminTelno,
String? adminTin,
String? faasType,
String? genCode,
String? dateSynced}) =>
PropertyInfo(
id: id ?? this.id,
assessedById: assessedById ?? this.assessedById,
assessedByName: assessedByName ?? this.assessedByName,
dateCreated: dateCreated ?? this.dateCreated,
dateModified: dateModified ?? this.dateModified,
transCode: transCode ?? this.transCode,
tdn: tdn ?? this.tdn,
pin: pin ?? this.pin,
fname: fname ?? this.fname,
mname: mname ?? this.mname,
lname: lname ?? this.lname,
bday: bday ?? this.bday,
address: address ?? this.address,
telno: telno ?? this.telno,
tin: tin ?? this.tin,
adminUser: adminUser ?? this.adminUser,
adminAddress: adminAddress ?? this.adminAddress,
adminTelno: adminTelno ?? this.adminTelno,
adminTin: adminTin ?? this.adminTin,
faasType: faasType ?? this.faasType,
genCode: genCode ?? this.genCode,
);
id: id ?? this.id,
assessedById: assessedById ?? this.assessedById,
assessedByName: assessedByName ?? this.assessedByName,
dateCreated: dateCreated ?? this.dateCreated,
dateModified: dateModified ?? this.dateModified,
transCode: transCode ?? this.transCode,
tdn: tdn ?? this.tdn,
pin: pin ?? this.pin,
fname: fname ?? this.fname,
mname: mname ?? this.mname,
lname: lname ?? this.lname,
bday: bday ?? this.bday,
address: address ?? this.address,
telno: telno ?? this.telno,
tin: tin ?? this.tin,
adminUser: adminUser ?? this.adminUser,
adminAddress: adminAddress ?? this.adminAddress,
adminTelno: adminTelno ?? this.adminTelno,
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"],
assessedById: json["assessed_by_id"],
assessedByName: json["assessed_by_name"],
// dateCreated: json["date_created"] == null
// ? null
// : DateTime.parse(json["date_created"]),
// dateModified: json["date_modified"] == null
// ? null
// : DateTime.parse(json["date_modified"]),
transCode: json["trans_code"],
tdn: json["tdn"],
pin: json["pin"],
fname: json["fname"],
mname: json["mname"],
lname: json["lname"],
bday: json["bday"],
address: json["address"],
telno: json["telno"],
tin: json["tin"],
adminUser: json["admin_user"],
adminAddress: json["admin_address"],
adminTelno: json["admin_telno"],
adminTin: json["admin_tin"],
faasType: json["faas_type"],
genCode: json["gen_code"],
);
id: json["id"],
assessedById: json["assessed_by_id"],
assessedByName: json["assessed_by_name"],
// dateCreated: json["date_created"] == null
// ? null
// : DateTime.parse(json["date_created"]),
// dateModified: json["date_modified"] == null
// ? null
// : DateTime.parse(json["date_modified"]),
transCode: json["trans_code"],
tdn: json["tdn"],
pin: json["pin"],
fname: json["fname"],
mname: json["mname"],
lname: json["lname"],
bday: json["bday"],
address: json["address"],
telno: json["telno"],
tin: json["tin"],
adminUser: json["admin_user"],
adminAddress: json["admin_address"],
adminTelno: json["admin_telno"],
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"],
assessedById: json["assessedById"],
assessedByName: json["assessedByName"],
// dateCreated: json["date_created"] == null
// ? null
// : DateTime.parse(json["date_created"]),
// dateModified: json["date_modified"] == null
// ? null
// : DateTime.parse(json["date_modified"]),
transCode: json["transCode"],
tdn: json["tdn"],
pin: json["pin"],
fname: json["fname"],
mname: json["mname"],
lname: json["lname"],
bday: json["bday"],
address: json["address"],
telno: json["telno"],
tin: json["tin"],
adminUser: json["adminUser"],
adminAddress: json["adminAddress"],
adminTelno: json["adminTelno"],
adminTin: json["adminTin"],
faasType: json["faasType"],
genCode: json["genCode"],
);
id: json["id"],
assessedById: json["assessedById"],
assessedByName: json["assessedByName"],
// dateCreated: json["date_created"] == null
// ? null
// : DateTime.parse(json["date_created"]),
// dateModified: json["date_modified"] == null
// ? null
// : DateTime.parse(json["date_modified"]),
transCode: json["transCode"],
tdn: json["tdn"],
pin: json["pin"],
fname: json["fname"],
mname: json["mname"],
lname: json["lname"],
bday: json["bday"],
address: json["address"],
telno: json["telno"],
tin: json["tin"],
adminUser: json["adminUser"],
adminAddress: json["adminAddress"],
adminTelno: json["adminTelno"],
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
};
}

View File

@ -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"],

View File

@ -3,7 +3,6 @@
// final familyBackground = familyBackgroundFromJson(jsonString);
import 'dart:convert';
import 'dart:ffi';
import '../utils/category.dart';
import '../utils/position.dart';

View File

@ -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,20 +61,20 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
),
Text(
sourceRemarks,
style: Theme.of(context).textTheme.caption,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(
height: 12,
),
FormBuilderTextField(
name: "remarks",
validator: FormBuilderValidators.required(
errorText: remarksRequired),
validator: FormBuilderValidators.required(
errorText: remarksRequired),
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),

View File

@ -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) {

View File

@ -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) {

View File

@ -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(

View File

@ -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(

View File

@ -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();
},

View File

@ -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 !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.minBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.minBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(value
.minBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.maxBaseUnitvalPercent !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.maxBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.maxBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(value
.maxBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.minUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue = double.parse(
value.minUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.minUnitvalSqrmtr
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue = double.parse(
value.maxUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.maxUnitvalSqrmtr
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.minAddBaseunitval != '0.00') {
setState(() {
_unitValue = double.parse(
value.minAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.minAddBaseunitval
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxAddBaseunitval != '0.00') {
setState(() {
_unitValue = double.parse(
value.maxAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.maxAddBaseunitval
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.minDeductBaserate != '0.00') {
setState(() {
_unitValue = double.parse(
value.minDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.minDeductBaserate
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxDeductBaserate != '0.00') {
setState(() {
_unitValue = double.parse(
value.maxDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC = value.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value.maxDeductBaserate
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
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
.item!.minBaseUnitvalPercent!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue': value
.item!.minBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(value
.item!
.minBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.item!.maxBaseUnitvalPercent !=
'0.00') {
setState(() {
_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
.item!.maxBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(value
.item!
.maxBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.item!.minUnitvalSqrmtr !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.minUnitvalSqrmtr!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.item!.minUnitvalSqrmtr
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.item!.maxUnitvalSqrmtr !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.maxUnitvalSqrmtr!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.item!.maxUnitvalSqrmtr
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.item!.minAddBaseunitval !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.minAddBaseunitval!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.item!.minAddBaseunitval
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.item!.maxAddBaseunitval !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.maxAddBaseunitval!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.item!.maxAddBaseunitval
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.item!.minDeductBaserate !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.minDeductBaserate!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'unitValue':
value.item!.minDeductBaserate
});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.item!.maxDeductBaserate !=
'0.00') {
setState(() {
_unitValue = double.parse(
value.item!.maxDeductBaserate!);
_className =
value.item!.componentName!;
_classId = value.item!.id!;
_withoutBUCC =
value.item!.withoutBucc == 1
? true
: false;
});
formKey.currentState!.patchValue({
'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();
},

View File

@ -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,40 +238,67 @@ 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,
foundation: foundation,
column: column,
beam: beam,
trussFraming: trussFraming,
roof: roof,
flooring: flooring,
walls: walls,
updateFoundation: updateFoundation,
updateColumn: updateColumn,
updateBeam: updateBeam,
updateFlooring: updateFlooring,
updateRoof: updateRoof,
updateTrussFraming: updateTrussFraming,
updateWalls: updateWalls));
StructuralMaterialsOfflinePage(
PrevBtn,
NextBtn,
foundationOthers: foundationOthers,
columOthers: columOthers,
beamsOthers: beamsOthers,
tfOthers: tfOthers,
roofOthers: roofOthers,
flooringOthers: flooringOthers,
wpOthers: wpOthers,
foundation: foundation,
column: column,
beam: beam,
trussFraming: trussFraming,
roof: roof,
flooring: flooring,
walls: walls,
updateFoundation: updateFoundation,
updateColumn: updateColumn,
updateBeam: updateBeam,
updateFlooring: updateFlooring,
updateRoof: updateRoof,
updateTrussFraming: updateTrussFraming,
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();
widget.triggerBlocEvent();
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.triggerBlocEvent();
});
await tempID.setBool('floorSketchSaved', false);
}
}

View File

@ -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()),
),
);
},
),
);
},
),
),
],
),
);
}
}

View File

@ -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),
)
],
);
}
}

View File

@ -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();
}

View File

@ -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'),
),
],
),
),
);
}
}

View File

@ -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', TextInputType.phone))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
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', TextInputType.phone))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
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(
"Survey No.", "", 'survey_no'))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField("Lot No.", "", 'lot_no'),
),
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'))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"TD / ARP No.", "", 'l_td_arp'),
),
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))
]),
const SizedBox(
height: 50,

File diff suppressed because it is too large Load Diff

View File

@ -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'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
customTextField("Address", "", 'address', TextInputType.text),
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: isOptional,
onChanged: (bool? value) {
setState(() {
isOptional = value!;
});
},
),
),
Text('Show optional information')
],
),
// Other widgets in the column
],
),
Visibility(
visible: isOptional,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: customTextField("Tel No.", "", 'tel_no'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Tel No.", "", 'tel_no', TextInputType.phone),
),
const SizedBox(width: 10.0),
Expanded(
flex: 1,
child: customTextField(
"TIN", "", 'tin', 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'))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Administrator / Benificial User", "", 'benificiary'),
const SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Administrator / Beneficial User",
"",
'benificiary',
TextInputType.text,
),
),
const SizedBox(width: 10.0),
Expanded(
flex: 1,
child: customTextField("TIN", "", 'benificiary_tin',
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'))
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child:
customTextField("Address", "", 'benificiary_address'),
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(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'))
]),
],
),
),
const SizedBox(height: 25),
CustomButton(
icon: const Icon(Icons.chevron_right, color: Colors.white),

View File

@ -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',
),
],
),
),
),
);
}
}

View File

@ -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,60 +430,63 @@ class _StructuralMaterialsOfflinePage
{
final tempID = await SharedPreferences.getInstance();
context
.read<StructuralMaterialOfflineBloc>()
.add(
AddStructuralMaterial(
id: 1,
bldgapprDetailsId: tempID.getInt('tempid')!,
assessedById: '',
assessedByName: '',
dateCreated: '',
dateModified: '',
foundation: foundationOthers
? [
offlineBldgKey.currentState!
.value['other_foundation']
]
: widget.foundation,
columns: columOthers
? [
offlineBldgKey.currentState!
.value['other_column']
]
: widget.column,
beams: beamsOthers
context.read<StructuralMaterialOfflineBloc>().add(
AddStructuralMaterial(
id: 1,
bldgapprDetailsId: tempID.getInt('tempid')!,
assessedById: '',
assessedByName: '',
dateCreated: '',
dateModified: '',
foundation: widget.foundationOthers
? [
offlineBldgKey.currentState!
.value['other_foundation']
]
: widget.foundation,
columns: widget
.columOthers
? [
offlineBldgKey
.currentState!.value['other_column']
]
: widget.column,
beams:
widget
.beamsOthers
? [
offlineBldgKey
.currentState!.value['other_beam']
]
: widget.beam,
trussFraming: tfOthers
? [
offlineBldgKey
.currentState!.value['other_tf']
]
: widget.trussFraming,
roof: roofOthers
trussFraming: widget.tfOthers
? [
offlineBldgKey
.currentState!.value['other_tf']
]
: widget.trussFraming,
roof:
widget.roofOthers
? [
offlineBldgKey
.currentState!.value['other_roof']
]
: widget.roof,
flooring: flooringOthers
flooring:
widget.flooringOthers
? [
offlineBldgKey.currentState!
.value['other_flooring']
]
: widget.flooring,
walls: wpOthers
? [
offlineBldgKey
.currentState!.value['other_wp']
]
: widget.walls,
others: const ["Others"],
genCode: '5th'));
walls: widget.wpOthers
? [
offlineBldgKey
.currentState!.value['other_wp']
]
: widget.walls,
others: const ["Others"],
genCode: '5th'));
widget.NextBtn();
}
;

View File

@ -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;
},
),
);
}

View File

@ -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,115 +106,145 @@ class _AddExtraItemsEditOffline extends State<AddExtraItemsEditOffline> {
Container(
margin: const EdgeInsets.only(
left: 0, top: 10, right: 0, bottom: 0),
child: FormBuilderDropdown(
name: 'extra_item',
autofocus: false,
decoration:
normalTextFieldStyle("Additional Item", ""),
items: widget.options
.map((e) => DropdownMenuItem(
value: e,
child: Text(e.componentName!),
))
.toList(),
onChanged: (value) {
if (value!.minBaseUnitvalPercent != '0.00') {
setState(() {
_unitValue = double.parse(
value.minBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minBaseUnitvalPercent});
}
if (value.maxBaseUnitvalPercent != '0.00') {
setState(() {
_unitValue = double.parse(
value.maxBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxBaseUnitvalPercent});
}
if (value.minUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue =
double.parse(value.minUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minUnitvalSqrmtr});
}
if (value.maxUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxUnitvalSqrmtr});
}
if (value.minAddBaseunitval != '0.00') {
setState(() {
_unitValue =
double.parse(value.minAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minAddBaseunitval});
}
if (value.maxAddBaseunitval != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxAddBaseunitval});
}
if (value.minDeductBaserate != '0.00') {
setState(() {
_unitValue =
double.parse(value.minDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minDeductBaserate});
}
if (value.maxDeductBaserate != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == '1' ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxDeductBaserate});
}
},
child: SizedBox(
height: 45,
width: 300,
child: FormBuilderDropdown(
name: 'extra_item',
autofocus: false,
decoration:
normalTextFieldStyle("Additional Item", ""),
items: widget.options
.map((e) => DropdownMenuItem(
value: e,
child: Text(e.componentName!),
))
.toList(),
onChanged: (value) {
if (value!.minBaseUnitvalPercent != '0.00') {
setState(() {
_unitValue = double.parse(
value.minBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue({
'unitValue': value.minBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(
value.minBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.maxBaseUnitvalPercent != '0.00') {
setState(() {
_unitValue = double.parse(
value.maxBaseUnitvalPercent!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue({
'unitValue': value.maxBaseUnitvalPercent
});
formKey.currentState!.patchValue({
'buccValue': (double.parse(
value.maxBaseUnitvalPercent!) *
100)
.toString()
});
}
if (value.minUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue =
double.parse(value.minUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minUnitvalSqrmtr});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxUnitvalSqrmtr != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxUnitvalSqrmtr!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxUnitvalSqrmtr});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.minAddBaseunitval != '0.00') {
setState(() {
_unitValue =
double.parse(value.minAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minAddBaseunitval});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxAddBaseunitval != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxAddBaseunitval!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxAddBaseunitval});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.minDeductBaserate != '0.00') {
setState(() {
_unitValue =
double.parse(value.minDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.minDeductBaserate});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
if (value.maxDeductBaserate != '0.00') {
setState(() {
_unitValue =
double.parse(value.maxDeductBaserate!);
_className = value.componentName!;
_classId = value.id!;
_withoutBUCC =
value.withoutBucc == 1 ? true : false;
});
formKey.currentState!.patchValue(
{'unitValue': value.maxDeductBaserate});
formKey.currentState!
.patchValue({'buccValue': '100'});
}
},
),
),
),
const SizedBox(height: 10),
@ -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(() {
_unitBase =
double.parse(unit.item!.unitValue);
_structureType = unit.item!.bldgType +
' - ' +
unit.item!.building;
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});
}
});
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"),
),

View File

@ -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"),
),

View File

@ -67,141 +67,137 @@ class _AdditionalItemEditPageOffline
if (state is AdditionalItemsLoaded) {
return Column(
children: [
Container(
height: 500,
child: Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(
left: 0, top: 20, right: 0, bottom: 10),
child: const Text('ADDITIONAL ITEMS',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18),
textAlign: TextAlign.left),
),
Align(
alignment: Alignment.topRight,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
),
onPressed: () {
context
.read<AdditionalItemsOfflineBloc>()
.add(ShowAdditionalItems());
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Text('ADD ITEM'), // <-- Text
SizedBox(
width: 5,
),
Icon(
// <-- Icon
Icons.add,
size: 24.0,
),
],
),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(
left: 0, top: 20, right: 0, bottom: 10),
child: const Text('ADDITIONAL ITEMS',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18),
textAlign: TextAlign.left),
),
Align(
alignment: Alignment.topRight,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
// ignore: prefer_const_literals_to_create_immutables
columns: [
const DataColumn(
label: Text('Items'),
onPressed: () {
context
.read<AdditionalItemsOfflineBloc>()
.add(ShowAdditionalItems());
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Text('ADD ITEM'), // <-- Text
SizedBox(
width: 5,
),
const DataColumn(
label: Text('Unit Value'),
Icon(
// <-- Icon
Icons.add,
size: 24.0,
),
const DataColumn(
label: Text('% of BUCC'),
),
const DataColumn(
label: Text('Market Value'),
),
const DataColumn(
label: Text('Action'),
)
],
rows: state.addItem.map((dataRow) {
return DataRow(
cells: [
DataCell(Text(dataRow.className)),
DataCell(Text(NumberFormat.currency(
locale: 'en-PH',
symbol: "",
).format(double.parse(
dataRow.baseUnitValue)))),
DataCell(
Text(dataRow.unitValue.toString())),
DataCell(Text(NumberFormat.currency(
locale: 'en-PH',
symbol: "",
).format(double.parse(
dataRow.adjustedMarketVal)))),
DataCell(Row(
children: [
InkWell(
child: Container(
height: 30,
width: 30,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: const Icon(
Icons.delete,
color: Colors.white,
size: 20.0,
),
),
onTap: () {
confirmAlertWithCancel(
context,
() =>
deleteItem(dataRow.id!),
() => null,
'Delete Item?',
"Are you sure you want to delete this item?");
},
),
const SizedBox(
width: 10,
),
InkWell(
child: Container(
height: 30,
width: 30,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: const Icon(
Icons.edit,
color: Colors.white,
size: 20.0,
),
),
onTap: () {},
),
],
))
],
);
}).toList(),
),
),
],
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
// ignore: prefer_const_literals_to_create_immutables
columns: [
const DataColumn(
label: Text('Items'),
),
const DataColumn(
label: Text('Unit Value'),
),
const DataColumn(
label: Text('% of BUCC'),
),
const DataColumn(
label: Text('Market Value'),
),
const DataColumn(
label: Text('Action'),
)
],
rows: state.addItem.map((dataRow) {
return DataRow(
cells: [
DataCell(Text(dataRow.className)),
DataCell(Text(NumberFormat.currency(
locale: 'en-PH',
symbol: "",
).format(double.parse(
dataRow.baseUnitValue)))),
DataCell(
Text(dataRow.unitValue.toString())),
DataCell(Text(NumberFormat.currency(
locale: 'en-PH',
symbol: "",
).format(double.parse(
dataRow.adjustedMarketVal)))),
DataCell(Row(
children: [
InkWell(
child: Container(
height: 30,
width: 30,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: const Icon(
Icons.delete,
color: Colors.white,
size: 20.0,
),
),
onTap: () {
confirmAlertWithCancel(
context,
() => deleteItem(dataRow.id!),
() => null,
'Delete Item?',
"Are you sure you want to delete this item?");
},
),
const SizedBox(
width: 10,
),
InkWell(
child: Container(
height: 30,
width: 30,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: const Icon(
Icons.edit,
color: Colors.white,
size: 20.0,
),
),
onTap: () {},
),
],
))
],
);
}).toList(),
),
),
],
),
),
),

View File

@ -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,81 +117,102 @@ class _EditBuildingOffline extends State<EditBuildingOffline> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: primary,
title: const Text('Building FAAS Edit'),
),
body: ProgressHUD(
padding: const EdgeInsets.all(24),
backgroundColor: Colors.black87,
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
child: BlocConsumer<StructuralMaterialOfflineBloc,
StructuralMaterialOfflineState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is SpecificStructuralMaterialLoaded) {
return BlocConsumer<UnitConstructionAdminBloc,
UnitConstructionAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is UnitConstructLoaded) {
final unit = state.unit;
return BlocConsumer<ClassComponentsAdminBloc,
ClassComponentsAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is ClassComponentsAdminLoaded) {
return Column(
children: [
NumberStepper(
numbers: const [1, 2, 3, 4, 5, 6, 7, 8],
activeStepColor: primary,
numberStyle:
const TextStyle(color: Colors.white),
lineColor: primary,
// activeStep property set to activeStep variable defined above.
activeStep: activeStep,
activeStepBorderColor: Colors.white,
activeStepBorderWidth: 1,
// This ensures step-tapping updates the activeStep.
onStepReached: (index) {
setState(() {
activeStep = index;
});
},
),
Expanded(
child: StatefulBuilder(builder:
(BuildContext context,
StateSetter setState) {
return Container(
child: content(PrevBtn, NextBtn, unit,
state.classes),
);
}),
),
],
);
}
return Container();
},
);
}
return Container();
},
);
}
return Container();
},
)));
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,
title: const Text('Building FAAS Edit'),
),
body: ProgressHUD(
padding: const EdgeInsets.all(24),
backgroundColor: Colors.black87,
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
child: BlocConsumer<StructuralMaterialOfflineBloc,
StructuralMaterialOfflineState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is SpecificStructuralMaterialLoaded) {
return BlocConsumer<UnitConstructionAdminBloc,
UnitConstructionAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is UnitConstructLoaded) {
final unit = state.unit;
return BlocConsumer<ClassComponentsAdminBloc,
ClassComponentsAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is ClassComponentsAdminLoaded) {
return Column(
children: [
NumberStepper(
numbers: const [
1,
2,
3,
4,
5,
6,
7,
8,
9
],
activeStepColor: primary,
numberStyle:
const TextStyle(color: Colors.white),
lineColor: primary,
// activeStep property set to activeStep variable defined above.
activeStep: activeStep,
activeStepBorderColor: Colors.white,
activeStepBorderWidth: 1,
// This ensures step-tapping updates the activeStep.
onStepReached: (index) {
setState(() {
activeStep = index;
});
},
),
Expanded(
child: StatefulBuilder(builder:
(BuildContext context,
StateSetter setState) {
return Container(
child: content(PrevBtn, NextBtn, unit,
state.classes),
);
}),
),
],
);
}
return Container();
},
);
}
return Container();
},
);
}
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();

View File

@ -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),
)
],
);
}
}

View File

@ -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,356 +41,309 @@ 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>(
listener: (context, state) async {
// if (state is GenDescLoading) {
// final progress = ProgressHUD.of(context);
// progress!.showWithText("Please wait...");
// }
// if (state is GenDescLoaded) {
// final progress = ProgressHUD.of(context);
// progress?.dismiss();
return BlocConsumer<GeneralDescriptionBloc, GeneralDescriptionState>(
listener: (context, state) async {
// if (state is GenDescLoading) {
// final progress = ProgressHUD.of(context);
// progress!.showWithText("Please wait...");
// }
// if (state is GenDescLoaded) {
// final progress = ProgressHUD.of(context);
// progress?.dismiss();
// final tempID = await SharedPreferences.getInstance();
// await tempID.setInt(
// 'totalValue', int.parse(state.gendesc.totalFloorArea!));
// await tempID.setString(
// 'actualUse', state.gendesc.actualUse!);
// final tempID = await SharedPreferences.getInstance();
// await tempID.setInt(
// 'totalValue', int.parse(state.gendesc.totalFloorArea!));
// await tempID.setString(
// 'actualUse', state.gendesc.actualUse!);
// }
// if (state is GenDescErrorState) {
// final progress = ProgressHUD.of(context);
// progress?.dismiss();
// }
},
builder: (context, state) {
if (state is SpecificGeneralDescriptionLoaded) {
final gendesc = state.gendesc;
return BlocConsumer<UnitConstructionAdminBloc,
UnitConstructionAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is UnitConstructLoaded) {
return FormBuilder(
key: offlineBldgEditKey,
initialValue: {
'bldg_permit': gendesc.bldgPermit,
'date_issued': gendesc.dateIssued.toString(),
'cct': gendesc.cct.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(),
'no_of_storeys': gendesc.noStoreys.toString(),
'area_of_1stFl': gendesc.area1Stfloor,
'area_of_2ndFl': gendesc.area2Ndfloor,
'area_of_3rdFl': gendesc.area3Rdfloor,
'area_of_4thFl': gendesc.area4Thfloor,
'total_area': gendesc.totalFloorArea.toString(),
'actual_use': gendesc.actualUse
},
enabled: true,
onChanged: () {
offlineBldgEditKey.currentState!.save();
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),
child: const Text('GENERAL DESCRIPTION',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18),
textAlign: TextAlign.left),
),
Container(
margin: const EdgeInsets.only(
left: 0,
top: 10,
right: 0,
bottom: 0),
child: FormBuilderDropdown(
name: 'bldg_type',
autofocus: false,
decoration: normalTextFieldStyle(
gendesc.bldgKind ??
"Kind of Building",
"Kind of Building"),
items: state.unit
.map((e) => DropdownMenuItem(
value: e,
child: Text(e.bldgType +
'-' +
e.building),
))
.toList(),
),
),
customDropDownField("Actual Use", "",
'actual_use', actual_use),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Bldg. Permit No.",
"",
'bldg_permit'),
),
const SizedBox(width: 10.0),
Expanded(
// optional flex property if flex is 1 because the default flex is 1
flex: 1,
child: customDatTimePicker(
"Certificate of Occupancy Issued ON",
"",
'date_issued'))
]),
customTextField(
"Condominium Certificate of Title (CCT)",
"",
'cct'),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customDatTimePicker(
"Certificate of Completion Issued ON",
"",
'coc_issued'),
),
const SizedBox(width: 10.0),
Expanded(
// optional flex property if flex is 1 because the default flex is 1
flex: 1,
child: customDatTimePicker(
"Certificate of Occupancy Issued ON",
"",
'coo_issued'))
]),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customDatTimePicker(
"Date Constructed /Completed",
"",
'date_cnstructed'),
),
const SizedBox(width: 10.0),
Expanded(
// optional flex property if flex is 1 because the default flex is 1
flex: 1,
child: customDatTimePicker(
"Date Occupied",
"",
'date_occupied'))
]),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Bldg. Age", "", 'bldg_age'),
),
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'))
]),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Area of 1st Floor",
"",
'area_of_1stFl'),
),
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'))
]),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField(
"Area of 3rd Floor",
"",
'area_of_3rdFl')),
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'))
]),
customTextField(
"Total Area", "", 'total_area'),
SizedBox(
height: 50,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
CustomButton(
icon: const Icon(
Icons.chevron_left_rounded,
color: Colors.white),
onPressed: () {
{
widget.PrevBtn();
}
;
},
),
CustomButton(
icon: const Icon(
Icons.chevron_right_rounded,
color: Colors.white),
onPressed: () {
{
offlineBldgEditKey.currentState!
.save();
var gendescData = GeneralDesc(
id: 1,
bldgapprDetailsId:
widget.tempId,
assessedById: "1",
assessedByName: 'hhs',
bldgKind: offlineBldgEditKey
.currentState
?.value['bldg_type']
?.building ??
gendesc.bldgKind,
strucType: offlineBldgEditKey
.currentState
?.value['bldg_type']
?.bldgType ??
gendesc.strucType,
bldgPermit: offlineBldgEditKey.currentState?.value['bldg_permit'] ??
gendesc.bldgPermit,
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(),
certOccupancyIssued: offlineBldgEditKey.currentState!.value['coo_issued'].toString(),
dateCompleted: offlineBldgEditKey.currentState!.value['date_cnstructed'].toString(),
dateOccupied: offlineBldgEditKey.currentState!.value['date_occupied'].toString(),
bldgAge: offlineBldgEditKey.currentState?.value['bldg_age']!,
noStoreys: offlineBldgEditKey.currentState?.value['no_of_storeys']!,
area1Stfloor: offlineBldgEditKey.currentState?.value['area_of_1stFl'],
area2Ndfloor: offlineBldgEditKey.currentState?.value['area_of_2ndFl'],
area3Rdfloor: offlineBldgEditKey.currentState?.value['area_of_3rdFl'],
area4Thfloor: offlineBldgEditKey.currentState?.value['area_of_4thFl'],
totalFloorArea: offlineBldgEditKey.currentState?.value['total_area'],
floorSketch: 'null',
actualUse: offlineBldgEditKey.currentState?.value['actual_use'],
unitValue: offlineBldgEditKey.currentState?.value['bldg_type']?.unitValue ?? gendesc.unitValue);
context
.read<
GeneralDescriptionBloc>()
.add(
UpdateGeneralDescription(
id: widget.tempId,
gendesc:
gendescData));
widget.NextBtn();
}
;
},
)
],
)
],
),
),
),
// }
// if (state is GenDescErrorState) {
// final progress = ProgressHUD.of(context);
// progress?.dismiss();
// }
},
builder: (context, state) {
if (state is SpecificGeneralDescriptionLoaded) {
final gendesc = state.gendesc;
return BlocConsumer<UnitConstructionAdminBloc,
UnitConstructionAdminState>(
listener: (context, state) {
// TODO: implement listener
},
builder: (context, state) {
if (state is UnitConstructLoaded) {
return FormBuilder(
key: offlineBldgEditKey,
initialValue: {
'bldg_permit': gendesc.bldgPermit,
'date_issued': gendesc.dateIssued.toString(),
'cct': gendesc.cct.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(),
'no_of_storeys': gendesc.noStoreys.toString(),
'area_of_1stFl': gendesc.area1Stfloor,
'area_of_2ndFl': gendesc.area2Ndfloor,
'area_of_3rdFl': gendesc.area3Rdfloor,
'area_of_4thFl': gendesc.area4Thfloor,
'total_area': gendesc.totalFloorArea.toString(),
'actual_use': gendesc.actualUse
},
enabled: true,
onChanged: () {
offlineBldgEditKey.currentState!.save();
debugPrint(
offlineBldgEditKey.currentState!.value.toString());
},
autovalidateMode: AutovalidateMode.disabled,
skipDisabled: true,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(
left: 0, top: 20, right: 0, bottom: 10),
child: const Text('GENERAL DESCRIPTION',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
textAlign: TextAlign.left),
),
Container(
margin: const EdgeInsets.only(
left: 0, top: 10, right: 0, bottom: 0),
child: FormBuilderDropdown(
name: 'bldg_type',
autofocus: false,
decoration: normalTextFieldStyle(
gendesc.bldgKind ?? "Kind of Building",
"Kind of Building"),
items: state.unit
.map((e) => DropdownMenuItem(
value: e,
child:
Text(e.bldgType + '-' + e.building),
))
.toList(),
),
);
}
return Container();
},
);
}
// if (state is GenDescErrorState) {
// return SomethingWentWrong(
// message: onError,
// onpressed: () {
// context.read<GeneralDescriptionBloc>().add(LoadGenDesc(
// id: widget.tempId, gendesc: GeneralDesc()));
// },
// );
// }
return Container();
},
),
),
),
],
),
),
customDropDownField(
"Actual Use", "", 'actual_use', actual_use),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: customTextField("Bldg. Permit No.", "",
'bldg_permit', TextInputType.phone),
),
const SizedBox(width: 10.0),
Expanded(
// optional flex property if flex is 1 because the default flex is 1
flex: 1,
child: customDatTimePicker(
"Certificate of Occupancy Issued ON", <