Skip to content

Instantly share code, notes, and snippets.

@kharitonovAL
Created July 19, 2021 17:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kharitonovAL/c8956f171958dbf76f66cb14bc4d2f09 to your computer and use it in GitHub Desktop.
Save kharitonovAL/c8956f171958dbf76f66cb14bc4d2f09 to your computer and use it in GitHub Desktop.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:uk_web/model/models.dart';
import 'package:uk_web/ui/requests_page/requests_page/web_ui/widgets/buttons.dart';
import 'package:uk_web/services/database/database_service_parse_server.dart';
import 'widgets/request_editor_page_widgets.dart';
class RequestEditorPage extends StatefulWidget {
final List<UserRequest> requestsList;
final UserRequest request;
final bool editRequest;
final String userRole;
RequestEditorPage({this.request, this.editRequest = false, this.requestsList, this.userRole});
@override
_RequestEditorPageState createState() => _RequestEditorPageState();
}
class _RequestEditorPageState extends State<RequestEditorPage> with TickerProviderStateMixin {
DBSParseServer _db = DBSParseServer();
final _requestTEC = TextEditingController();
final _flatNumberTEC = TextEditingController();
final _phoneNumberTEC = TextEditingController();
final _nameTEC = TextEditingController();
final _requestNoteTEC = TextEditingController();
final _responseTEC = TextEditingController();
final _cancelReasonTEC = TextEditingController();
bool _cancelReasonValidator = false;
bool _requestValidator = false;
bool _phoneNumberValidator = false;
bool _nameValidator = false;
bool _flatNumberValidator = false;
bool _isFailure = false;
bool _isPaid = false;
bool _isMaintenance = false;
bool _isScheduled = false;
String _jobTypeTitle;
String _selectedAddress;
String _selectedFlatNumber;
String _currentPartnerTitle = 'ООО УК \"...\"';
String _currentMaster;
String _currentStaff;
String _selectedAccountNumber;
double _currentDebt;
int _requestNumber;
DateTime _requestDate;
DateTime _responseDate;
var _jobTypeColor = Colors.transparent;
Owner _currentOwner;
UserRequest _request;
@override
void initState() {
if (widget.editRequest) _initFields();
if (!kIsWeb) _responseDate = _setResponseDate();
super.initState();
}
DateTime _setResponseDate() {
final today = DateTime.now().toLocal();
final todayEvening = DateTime(today.year, today.month, today.day, 17);
final tomorrow = DateTime(today.year, today.month, today.day, 12).add(Duration(days: 1));
final date = today.hour < 12 ? todayEvening : tomorrow;
return date;
}
@override
Widget build(BuildContext context) {
return kIsWeb ? _buildWebUI() : _buildMobileUI();
}
Scaffold _buildWebUI() {
return Scaffold(
appBar: AppBar(
title: widget.editRequest ? NewUserRequestHeader(userRequest: _request, responseDate: _responseDate) : null),
body: Padding(
padding: EdgeInsets.all(16),
child: SizedBox(
height: MediaQuery.of(context).size.height - AppBar().preferredSize.height,
child: Stack(
fit: StackFit.expand,
children: [
_buildWebUIWidgets(),
_request != null && (_request.status == RS.closed || _request.status == RS.canceled)
? Container()
: _buildCalendar()
],
),
),
),
);
}
Widget _buildMobileUI() {
return Scaffold(
appBar: AppBar(title: Text('Заявка')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 16, 8, 8),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
if (!widget.editRequest)
RequestNumberText(
responseDate: _responseDate ?? _setResponseDate(),
onRequestDateChange: (value) => _requestDate = value,
onRequestNumberChange: (value) => _requestNumber = value,
),
if (widget.editRequest) NewUserRequestHeader(userRequest: _request, responseDate: _responseDate),
if (widget.editRequest) UserRequestShiftDateHistory(userRequest: _request),
if (widget.editRequest) UserRequestPhotoButton(userRequest: _request),
// _showCalendarInMobileUIButton(),
Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 16, 8, 16),
child: Column(
children: [
UserRequestDescriptionTextField(
userRequest: _request,
userRequestTEC: _requestTEC,
userRequestValidator: _requestValidator,
),
if (widget.editRequest && widget.request.requestNote.isNotEmpty)
UserRequestNoteTextField(userRequest: _request, userRequestNoteTEC: _requestNoteTEC),
if (!widget.editRequest)
UserRequestNoteTextField(userRequest: _request, userRequestNoteTEC: _requestNoteTEC),
],
),
),
),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
IsFailureCheckBox(
userRequest: _request,
isFailure: _isFailure,
onIsFailureStatusChanged: (value) => setState(() => _isFailure = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
),
IsPaidCheckBox(
userRequest: _request,
isPaid: _isPaid,
onIsPaidStatusChanged: (value) => setState(() => _isPaid = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
),
IsMaintenanceCheckBox(
userRequest: _request,
isMaintenance: _isMaintenance,
onIsMaintenanceStatusChanged: (value) => setState(() => _isMaintenance = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
),
IsScheduledCheckBox(
userRequest: _request,
isScheduled: _isScheduled,
onIsScheduledStatusChanged: (value) => setState(() => _isScheduled = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 0, 0),
child: JobTypeDropDown(
userRequest: _request,
jobTypeTitle: _jobTypeTitle,
jobTypeColor: _jobTypeColor,
onJobTypeColorChanged: (value) => setState(() => _jobTypeColor = value),
onJobTypeTitleChanged: (value) => setState(() => _jobTypeTitle = value),
),
)
]),
),
),
Card(
child: Padding(
padding: EdgeInsets.all(8),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
AddressDropDown(
userRequest: _request,
selectedAddress: _selectedAddress,
onSelectedAddressChanged: (value) => setState(() => _selectedAddress = value),
onSelectedAccountNumberChanged: () => setState(() => _selectedAccountNumber = null),
onClear: () => _flatNumberTEC.clear()),
FlatNumberTextField(
userRequest: _request,
flatNumberTEC: _flatNumberTEC,
flatNumberValidator: _flatNumberValidator,
onSelectedFlatNumberChanged: (value) => setState(() => _selectedFlatNumber = value),
onSelectedAccountNumberChanged: () => setState(() => _selectedFlatNumber = null),
),
if (_selectedAddress != null && _selectedFlatNumber != null)
Container(
height: 50,
child: FittedBox(
fit: BoxFit.fitWidth,
child: AccountListDropDown(
userRequest: _request,
address: _selectedAddress,
flatNumber: _selectedFlatNumber,
selectedAccountNumber: _selectedAccountNumber,
onCurrentDebtChange: (newDebt) => _currentDebt = newDebt,
onAccountNumberChange: (newAccountNumber) =>
setState(() => _selectedAccountNumber = newAccountNumber),
onAccountChange: (newAccount) => _autoFillOwnerInfo(account: newAccount),
),
),
),
UserFirstAndLastNameTextField(
userRequest: _request,
nameTEC: _nameTEC,
nameValidator: _nameValidator,
),
UserPhoneNumberTextField(
userRequest: _request,
phoneNumberTEC: _phoneNumberTEC,
phoneNumberValidator: _phoneNumberValidator,
),
if (widget.editRequest && _request.userToken != null) _ownerFutureBuilder()
]),
),
),
Card(
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Подрядчик:', style: TextStyle(fontSize: 16)),
SelectPartnerDropDown(
currentPartnerTitle: _currentPartnerTitle,
userRequest: _request,
onPartnerChanged: (newPartner) => setState(() => _currentPartnerTitle = newPartner),
),
SelectMasterDropDown(
currentMaster: _currentMaster,
userRequest: _request,
onMasterChanged: (newMaster) => setState(() => _currentMaster = newMaster),
),
SelectStaffDropdown(
currentPartnerTitle: _currentPartnerTitle,
currentStaff: _currentStaff,
userRequest: _request,
onStaffChanged: (newStaff) => setState(() => _currentStaff = newStaff),
),
SizedBox(height: 8),
if (widget.editRequest) SeenByStaffText(userRequest: _request),
],
),
),
),
if (_request != null && _request.status == RS.canceled) Divider(),
if (_request != null && _request.status == RS.canceled) CancelReasonText(userRequest: _request),
if (_request != null && _request.status == RS.closed) Divider(),
if (_request != null && _request.status == RS.closed) UserRequestDoneResultText(userRequest: _request),
Wrap(spacing: 16, children: _buttonsList()),
]),
),
),
);
// todo: add calendar to showAlert
// _buildTableCalendar(), Expanded(child: _buildEventList())
}
ElevatedButton _showCalendarInMobileUIButton() {
return ElevatedButton(
child: Text('Показать календарь'),
onPressed: () {
showDialog(
context: context,
builder: (contex) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
title: Text('Календарь'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildTableCalendar(width: MediaQuery.of(context).size.width),
// Expanded(child: _buildEventList()),
],
),
));
});
});
},
);
}
Widget _buildWebUIWidgets() {
return FractionallySizedBox(
widthFactor: .75,
alignment: Alignment.centerLeft,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.editRequest
? Wrap(
spacing: 16,
children: [
UserRequestHeaderText(userRequest: _request),
UserRequestShiftDateHistory(userRequest: _request),
UserRequestPhotoButton(userRequest: _request)
],
)
: RequestNumberText(
responseDate: _responseDate ?? _setResponseDate(),
onRequestDateChange: (value) => _requestDate = value,
onRequestNumberChange: (value) => _requestNumber = value,
),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: UserRequestDescriptionTextField(
userRequest: _request,
userRequestTEC: _requestTEC,
userRequestValidator: _requestValidator,
),
),
SizedBox(width: 8),
Container(
width: 300,
child: UserRequestNoteTextField(userRequest: _request, userRequestNoteTEC: _requestNoteTEC),
),
],
),
SizedBox(height: 8),
Row(children: [
IsFailureCheckBox(
userRequest: _request,
isFailure: _isFailure,
onIsFailureStatusChanged: (value) => setState(() => _isFailure = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
),
SizedBox(width: 8),
IsPaidCheckBox(
userRequest: _request,
isPaid: _isPaid,
onIsPaidStatusChanged: (value) => setState(() => _isPaid = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
),
SizedBox(width: 8),
IsMaintenanceCheckBox(
userRequest: _request,
isMaintenance: _isMaintenance,
onIsMaintenanceStatusChanged: (value) => setState(() => _isMaintenance = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isScheduledNewStatus: (value) => setState(() => _isScheduled = value),
),
SizedBox(width: 8),
IsScheduledCheckBox(
userRequest: _request,
isScheduled: _isScheduled,
onIsScheduledStatusChanged: (value) => setState(() => _isScheduled = value),
isFailureNewStatus: (value) => setState(() => _isFailure = value),
isPaidNewStatus: (value) => setState(() => _isPaid = value),
isMaintenanceNewStatus: (value) => setState(() => _isMaintenance = value),
),
SizedBox(width: 32),
Text('Тип работы:', style: TextStyle(fontSize: 16)),
SizedBox(width: 8),
JobTypeDropDown(
userRequest: _request,
jobTypeTitle: _jobTypeTitle,
jobTypeColor: _jobTypeColor,
onJobTypeColorChanged: (value) => setState(() => _jobTypeColor = value),
onJobTypeTitleChanged: (value) => setState(() => _jobTypeTitle = value),
),
]),
],
),
),
),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
children: [
Text('Адрес:', style: TextStyle(fontSize: 16)),
AddressDropDown(
userRequest: _request,
selectedAddress: _selectedAddress,
onSelectedAddressChanged: (value) => setState(() => _selectedAddress = value),
onSelectedAccountNumberChanged: () => setState(() => _selectedAccountNumber = null),
onClear: () => _flatNumberTEC.clear()),
SizedBox(width: 16),
Container(
width: 200,
child: FlatNumberTextField(
userRequest: _request,
flatNumberTEC: _flatNumberTEC,
flatNumberValidator: _flatNumberValidator,
onSelectedFlatNumberChanged: (value) => setState(() => _selectedFlatNumber = value),
onSelectedAccountNumberChanged: () => setState(() => _selectedFlatNumber = null),
),
),
Text('Лицевой счет:', style: TextStyle(fontSize: 16)),
SizedBox(width: 16),
if (_selectedAddress != null && _selectedFlatNumber != null)
AccountListDropDown(
userRequest: _request,
address: _selectedAddress,
flatNumber: _selectedFlatNumber,
selectedAccountNumber: _selectedAccountNumber,
onCurrentDebtChange: (newDebt) => _currentDebt = newDebt,
onAccountNumberChange: (newAccountNumber) =>
setState(() => _selectedAccountNumber = newAccountNumber),
onAccountChange: (newAccount) => _autoFillOwnerInfo(account: newAccount),
)
],
),
Row(children: [
Flexible(
child: UserFirstAndLastNameTextField(
userRequest: _request,
nameTEC: _nameTEC,
nameValidator: _nameValidator,
),
),
SizedBox(width: 16),
Flexible(
child: UserPhoneNumberTextField(
userRequest: _request,
phoneNumberTEC: _phoneNumberTEC,
phoneNumberValidator: _phoneNumberValidator,
),
),
if (widget.editRequest && _request.userToken != null) _ownerFutureBuilder()
]),
],
),
),
),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(children: [
Row(
children: [
Text('Подрядчик:', style: TextStyle(fontSize: 16)),
SizedBox(width: 8),
SelectPartnerDropDown(
currentPartnerTitle: _currentPartnerTitle,
userRequest: _request,
onPartnerChanged: (newPartner) => setState(() => _currentPartnerTitle = newPartner),
),
SizedBox(width: 8),
SelectMasterDropDown(
currentMaster: _currentMaster,
userRequest: _request,
onMasterChanged: (newMaster) => setState(() => _currentMaster = newMaster),
),
SizedBox(width: 8),
SelectStaffDropdown(
currentPartnerTitle: _currentPartnerTitle,
currentStaff: _currentStaff,
userRequest: _request,
onStaffChanged: (newStaff) => setState(() => _currentStaff = newStaff),
),
SizedBox(width: 8),
if (widget.editRequest) SeenByStaffText(userRequest: _request),
],
),
]),
),
),
Divider(),
Wrap(
spacing: 16,
runSpacing: 16,
children: _buttonsList(),
),
if (_request != null && _request.status == RS.canceled) Divider(),
if (_request != null && _request.status == RS.canceled) CancelReasonText(userRequest: _request),
if (_request != null && _request.status == RS.closed) Divider(),
if (_request != null && _request.status == RS.closed) UserRequestDoneResultText(userRequest: _request)
],
),
),
);
}
FutureBuilder _ownerFutureBuilder() {
return FutureBuilder<Owner>(
future: _db.getOwnerById(ownerId: widget.request.ownerId),
builder: (context, future) {
if (future.hasData) {
final owner = future.data;
if (owner.deviceTokenList != null && owner.deviceTokenList.isNotEmpty) {
return NotifyUserButton(userRequest: _request, owner: future.data);
} else {
return Container();
}
}
return CircularProgressIndicator();
});
}
List<Widget> _buttonsList() {
return [
Buttons.cancelRaisedButton(context),
if (_request != null && _request.status != RS.canceled)
if (_request != null && _request.status != RS.closed)
SaveUserRequestButton(
onUserRequestSave: _saveRequest,
requestValidator: _requestValidator,
phoneNumberValidator: _phoneNumberValidator,
nameValidator: _nameValidator,
flatNumberValidator: _flatNumberValidator,
selectedAccountNumber: _selectedAccountNumber,
selectedAddress: _selectedAddress,
),
if (!widget.editRequest)
SaveUserRequestButton(
onUserRequestSave: _saveRequest,
requestValidator: _requestValidator,
phoneNumberValidator: _phoneNumberValidator,
nameValidator: _nameValidator,
flatNumberValidator: _flatNumberValidator,
selectedAccountNumber: _selectedAccountNumber,
selectedAddress: _selectedAddress,
),
if (widget.editRequest && _request.status != RS.closed && _request.status != RS.canceled)
SubmitRequestForWorkButton(
userRequest: _request,
owner: _currentOwner,
currentMaster: _currentMaster,
currentPartnerTitle: _currentPartnerTitle,
currentStaff: _currentStaff,
jobTypeTitle: _jobTypeTitle,
userRole: widget.userRole,
onChangeStatus: (changeStatus) => _saveRequest(changeStatus: changeStatus),
),
if (widget.editRequest && kIsWeb)
PrintButton(request: _request, partnerTitle: _currentPartnerTitle, staff: _currentStaff, debt: _currentDebt),
if (widget.editRequest && _request != null && _request.status != RS.closed && _request.status != RS.canceled)
CancelUserRequestButton(
userRequest: _request,
cancelReasonTEC: _cancelReasonTEC,
cancelReasonValidator: _cancelReasonValidator,
),
if (_request != null && _request.status != RS.closed && _request.status != RS.canceled)
CloseUserRequestButton(
userRequest: _request,
responseTEC: _responseTEC,
)
];
}
void _autoFillOwnerInfo({@required Account account}) async {
print('_autoFillOwnerInfo() called');
final ownerList = await _db.getOwnerList();
final owner = ownerList.firstWhere((owner) => owner.accountId == account.objectId);
_currentOwner = owner;
_nameTEC.text = owner.name;
_phoneNumberTEC.text = '${owner.phoneNumber}';
_currentDebt = account.debt;
}
void _initFields() {
print('_initFields() called');
_request = widget.request;
_requestTEC.text = widget.request.userRequest;
_requestNoteTEC.text = widget.request.requestNote;
_flatNumberTEC.text = '${widget.request.flatNumber}';
_phoneNumberTEC.text = '${widget.request.phoneNumber}';
_nameTEC.text = widget.request.userName;
_selectedAddress = widget.request.address;
_selectedFlatNumber = '${widget.request.flatNumber}';
_selectedAccountNumber = widget.request.accountNumber;
_isPaid = widget.request.isPaid ?? false;
_isFailure = widget.request.isFailure ?? false;
_isMaintenance = widget.request.isMaintenance ?? false;
_isScheduled = widget.request.isScheduled ?? false;
_jobTypeTitle = widget.request.jobType;
_currentPartnerTitle = widget.request.partnerTitle;
_currentMaster = widget.request.masterStaff;
_currentStaff = widget.request.partnerStaff;
_currentDebt = widget.request.debt;
_requestDate = widget.request.requestDate;
_responseDate = widget.request.responseDate;
}
Future _saveRequest({bool changeStatus = false}) async {
// save request logic here
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment