support null safety 3

merge-requests/2/head
nextwo 3 years ago
parent 5644ccad7c
commit 33a2e2127d

@ -137,7 +137,7 @@ class DeviceTransferProvider extends ChangeNotifier {
required User user,
required bool isSender,
required String requestId,
required DeviceTransfer oldModel,
required DeviceTransfer? oldModel,
required DeviceTransferInfo newModel,
}) async {
Map<String, dynamic> body = {

@ -126,7 +126,7 @@ class GasRefillProvider extends ChangeNotifier {
Future<int> updateModel({
required String host,
required User user,
required GasRefillModel oldModel,
required GasRefillModel? oldModel,
required GasRefillModel newModel,
}) async {
Map<String, dynamic> body = {
@ -154,7 +154,7 @@ class GasRefillProvider extends ChangeNotifier {
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
oldModel.fromGasRefillModel(newModel);
oldModel?.fromGasRefillModel(newModel);
notifyListeners();
}
return response.statusCode;

@ -13,7 +13,7 @@ class Department{
name: parsedJson["dept_name"] ?? parsedJson["value"],
);
}
factory Department.fromDepartment(Department department){
factory Department.fromDepartment(Department? department){
return Department(
id: department?.id,
name: department?.name,

@ -48,17 +48,17 @@ class DeviceTransferInfo {
return true;
}
fromDetails(DeviceTransferInfo old, {bool withSignature = true}) {
userId = old.userId;
name = old.name;
client = old.client != null ? Hospital.fromHospital(old.client!) : null;
fromDetails(DeviceTransferInfo? old, {bool withSignature = true}) {
userId = old?.userId;
name = old?.name;
client = old?.client != null ? Hospital.fromHospital(old?.client) : null;
department =
department != null ? Department.fromDepartment(old.department!) : null;
workingHours = old.workingHours;
travelingHours = old.travelingHours;
comment = old.comment;
if (withSignature) signature = old.signature;
status = old.status;
department != null ? Department.fromDepartment(old?.department!) : null;
workingHours = old?.workingHours;
travelingHours = old?.travelingHours;
comment = old?.comment;
if (withSignature) signature = old?.signature;
status = old?.status;
}
factory DeviceTransferInfo.fromJson(

@ -10,7 +10,7 @@ class GasRefillDetails {
this.type,
this.cylinderSize,
this.requestedQuantity,
this.deliveredQuantity,
this.deliveredQuantity, required model,
});
bool validate() {

@ -14,7 +14,7 @@ class Hospital{
);
}
factory Hospital.fromHospital(Hospital hospital){
factory Hospital.fromHospital(Hospital? hospital){
return Hospital(
id: hospital?.id,
name: hospital?.name,

@ -1,16 +1,26 @@
.import 'dart:convert';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import '../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/device_transfer_provider.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/device/device_transfer.dart';
import '../../../models/device/device_transfer_info.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../../app_style/sizing.dart';
import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_button.dart';
import '../../widgets/e_signature/e_signature.dart';
import '../../widgets/loaders/loading_manager.dart';
import '../../widgets/status/gas_refill/gas_status.dart';
import '../../widgets/titles/app_sub_title.dart';
class UpdateDeviceTransfer extends StatefulWidget {
final DeviceTransfer? model;
@ -45,9 +55,9 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
_isLoading =true;
setState(() {});
int? status = await _deviceTransferProvider?.updateRequest(
user: _userProvider.user,
host: _settingProvider.host,
requestId: widget.model.,
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
requestId: widget.model?.id??"",
isSender: widget.isSender??false,
newModel: _formModel,
oldModel: widget.model
@ -81,8 +91,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
@override
void initState() {
_formModel.fromDetails(widget.isSender
? widget.model.sender : widget.model.receiver,
_formModel.fromDetails((widget.isSender??false) ? widget.model?.sender : widget.model?.receiver,
withSignature: false
);
super.initState();
@ -96,7 +105,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context,listen: false);
@ -120,7 +129,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
padding: const EdgeInsets.all(8.0),
child: Text(
"Edit Transfer Device",
style: Theme.of(context).textTheme.headline5.copyWith(
style: Theme.of(context).textTheme.headline5?.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 28,
fontWeight: FontWeight.bold
@ -133,7 +142,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
const SizedBox(height: 4,),
ATextFormField(
initialValue: _formModel?.comment,
initialValue: _formModel.comment??"",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.text,
@ -142,10 +151,10 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
},
),
const SizedBox(height: 8,),
ASubTitle(_subtitle.travelingHours),
ASubTitle(_subtitle?.travelingHours??""),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _formModel?.travelingHours,
initialValue: _formModel.travelingHours??"",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
@ -154,10 +163,10 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
},
),
const SizedBox(height: 8,),
ASubTitle(_subtitle.workingHours),
ASubTitle(_subtitle?.workingHours??""),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _formModel?.workingHours,
initialValue: _formModel.workingHours??"",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
@ -165,20 +174,8 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
_formModel.workingHours = value;
},
),
// const SizedBox(height: 8,),
// const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
// const SizedBox(height: 4,),
// DepartmentButton(
// department: _formModel.senderDepartment,
// onDepartmentPick: (department){
// _formModel.senderDepartment = department;
// setState(() {});
// },
// ),
const SizedBox(height: 8,),
ASubTitle(_subtitle.status),
ASubTitle(_subtitle?.status??""),
const SizedBox(height: 4,),
GasStatusMenu(
initialValue: _formModel.status,
@ -193,9 +190,9 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
ESignature(
oldSignature: widget.isSender
? widget.model.sender.signature
: widget.model.receiver.signature,
oldSignature: (widget.isSender??false)
? widget.model?.sender?.signature
: widget.model?.receiver?.signature,
newSignature: _signature,
onSaved: (signature){
_signature = signature;
@ -205,7 +202,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
Padding(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.update,
text: _subtitle?.update??"",
onPressed: _update,
),
),

@ -1,21 +1,20 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/register.dart';
import 'package:test_sa/views/pages/user/land_page.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../widgets/buttons/app_outlined_button.dart';
import '../../controllers/http_status_manger/http_status_manger.dart';
import '../../controllers/localization/localization.dart';
import '../../controllers/providers/api/user_provider.dart';
import '../../controllers/providers/settings/setting_provider.dart';
import '../../controllers/validator/validator.dart';
import '../../models/subtitle.dart';
import '../../models/user.dart';
import '../app_style/sizing.dart';
import '../widgets/app_text_form_field.dart';
import '../widgets/buttons/app_button.dart';
import '../widgets/loaders/loading_manager.dart';
import 'user/land_page.dart';
class Login extends StatefulWidget {
static final String id = "/login";
@ -25,14 +24,14 @@ class Login extends StatefulWidget {
}
class _LoginState extends State<Login> {
UserProvider _userProvider;
SettingProvider _settingProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
User _user = User();
bool _obscurePassword = true;
bool _firstTime = true;
double _height;
double _width;
String _payload;
late double _height;
late double _width;
late String _payload;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -42,12 +41,12 @@ class _LoginState extends State<Login> {
_settingProvider = Provider.of<SettingProvider>(context);
_height = MediaQuery.of(context).size.height;
_width = MediaQuery.of(context).size.width;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
isLoading: _userProvider.isLoading || !_settingProvider.isLoaded,
isLoading: (_userProvider?.isLoading??false) || !(_settingProvider?.isLoaded??false),
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
@ -77,12 +76,12 @@ class _LoginState extends State<Login> {
height: 24 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _user?.userName,
hintText: _subtitle.name,
initialValue: _user?.userName??"",
hintText: _subtitle?.name??"",
textAlign: TextAlign.left,
style: Theme.of(context).textTheme.bodyText1,
prefixIconData: Icons.account_circle,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage,
validator: (value) => Validator.hasValue(value) ? null : _subtitle?.nameValidateMessage,
textInputType: TextInputType.name,
onSaved: (value) {
_user.userName = value;
@ -90,13 +89,13 @@ class _LoginState extends State<Login> {
),
SizedBox(height: 12),
ATextFormField(
initialValue: _user?.password,
hintText: _subtitle.password,
initialValue: _user.password,
hintText: _subtitle?.password??"",
obscureText: _obscurePassword,
style: Theme.of(context).textTheme.bodyText1,
prefixIconData: Icons.vpn_key_sharp,
textAlign: TextAlign.left,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle?.passwordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
@ -109,22 +108,22 @@ class _LoginState extends State<Login> {
height: 32 * AppStyle.getScaleFactor(context),
),
AButton(
text: _subtitle.signIn,
text: _subtitle?.signIn??"",
onPressed: () async {
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
int status = await _userProvider.login(
if (!(_formKey.currentState?.validate()??false)) return;
_formKey.currentState?.save();
int? status = await _userProvider?.login(
user: _user,
host: _settingProvider.host,
host: _settingProvider?.host??"",
);
if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user);
if (_userProvider.user.isActive)
if (status !=null && status >= 200 && status < 300) {
_settingProvider?.setUser(_userProvider?.user??User());
if (_userProvider?.user?.isActive??false)
Navigator.of(context).pushNamed(LandPage.id);
else
Fluttertoast.showToast(msg: _subtitle.activationAlert);
Fluttertoast.showToast(msg: _subtitle?.activationAlert??"");
} else {
String errorMessage = status == 400 ? _subtitle.wrongEmailOrPassword : HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
String errorMessage = status == 400 ? _subtitle?.wrongEmailOrPassword??"" : HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));

@ -2,19 +2,21 @@ import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/departments/department_button.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../controllers/http_status_manger/http_status_manger.dart';
import '../../controllers/localization/localization.dart';
import '../../controllers/providers/api/user_provider.dart';
import '../../controllers/providers/settings/setting_provider.dart';
import '../../controllers/validator/validator.dart';
import '../../models/subtitle.dart';
import '../../models/user.dart';
import '../widgets/app_text_form_field.dart';
import '../widgets/buttons/app_back_button.dart';
import '../widgets/buttons/app_button.dart';
import '../widgets/departments/department_button.dart';
import '../widgets/hospitals/hospital_button.dart';
import '../widgets/loaders/loading_manager.dart';
class Register extends StatefulWidget {
static final String id = "/register";
@ -24,10 +26,10 @@ class Register extends StatefulWidget {
}
class _RegisterState extends State<Register> {
UserProvider _userProvider;
SettingProvider _settingProvider;
double _width;
double _height;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
late double _width;
late double _height;
User _user = User();
bool _obscurePassword = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -39,11 +41,11 @@ class _RegisterState extends State<Register> {
_settingProvider = Provider.of<SettingProvider>(context);
_width = MediaQuery.of(context).size.width;
_height = MediaQuery.of(context).size.height;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
key: _scaffoldKey,
body: LoadingManager(
isLoading: _userProvider.isLoading,
isLoading: _userProvider?.isLoading??false,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
@ -69,10 +71,10 @@ class _RegisterState extends State<Register> {
),
ATextFormField(
initialValue: _user.userName,
hintText: _subtitle.name,
hintText: _subtitle?.name??"",
prefixIconData: Icons.account_circle,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage,
validator: (value) => Validator.hasValue(value) ? null : _subtitle?.nameValidateMessage,
onSaved: (value) {
_user.userName = value;
},
@ -80,11 +82,11 @@ class _RegisterState extends State<Register> {
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.email,
hintText: _subtitle.email,
hintText: _subtitle?.email??"",
prefixIconData: Icons.email,
textInputType: TextInputType.emailAddress,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.isEmail(value) ? null : _subtitle.emailValidateMessage,
validator: (value) => Validator.isEmail(value) ? null : _subtitle?.emailValidateMessage,
onSaved: (value) {
_user.email = value;
},
@ -92,11 +94,11 @@ class _RegisterState extends State<Register> {
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.password,
hintText: _subtitle.password,
hintText: _subtitle?.password??"",
prefixIconData: Icons.vpn_key_sharp,
style: Theme.of(context).textTheme.headline6,
obscureText: _obscurePassword,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle?.passwordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
@ -112,10 +114,10 @@ class _RegisterState extends State<Register> {
ATextFormField(
initialValue: _user.password,
prefixIconData: Icons.vpn_key_sharp,
hintText: _subtitle.confirmPassword,
hintText: _subtitle?.confirmPassword??"",
style: Theme.of(context).textTheme.headline6,
obscureText: _obscurePassword,
validator: (value) => _user.password == value ? null : _subtitle.confirmPasswordValidateMessage,
validator: (value) => _user.password == value ? null : _subtitle?.confirmPasswordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
@ -139,11 +141,11 @@ class _RegisterState extends State<Register> {
),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.phoneNumber,
hintText: _subtitle.phoneNumber,
initialValue: _user.phoneNumber??"",
hintText: _subtitle?.phoneNumber??"",
style: Theme.of(context).textTheme.headline6,
prefixIconData: Icons.phone_android,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle?.phoneNumberValidateMessage,
textInputType: TextInputType.phone,
onSaved: (value) {
_user.phoneNumber = value;
@ -151,12 +153,12 @@ class _RegisterState extends State<Register> {
),
SizedBox(height: 8),
ATextFormField(
initialValue: _user.whatsApp,
hintText: _subtitle.whatsApp,
initialValue: _user.whatsApp??"",
hintText: _subtitle?.whatsApp??"",
style: Theme.of(context).textTheme.headline6,
prefixIconData: FontAwesomeIcons.whatsapp,
prefixIconSize: 36,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle?.phoneNumberValidateMessage,
textInputType: TextInputType.phone,
onSaved: (value) {
_user.whatsApp = value;
@ -164,37 +166,37 @@ class _RegisterState extends State<Register> {
),
const SizedBox(height: 12),
AButton(
text: _subtitle.signUp,
text: _subtitle?.signUp??"",
onPressed: () async {
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
if (!(_formKey.currentState?.validate()??false)) return;
_formKey.currentState?.save();
if (_user.hospital == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.hospitalRequired),
content: Text(_subtitle?.hospitalRequired??""),
));
return;
}
if (_user.department == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.unitRequired),
content: Text(_subtitle?.unitRequired??""),
));
return;
}
int status = await _userProvider.register(
int? status = await _userProvider?.register(
user: _user,
host: _settingProvider.host,
host: _settingProvider?.host??"",
);
if (status >= 200 && status < 300) {
Fluttertoast.showToast(msg: _subtitle.activationAlert);
if (status != null && status >= 200 && status < 300) {
Fluttertoast.showToast(msg: _subtitle?.activationAlert??"");
Navigator.of(context).pop();
} else {
String errorMessage = status == 402
? _subtitle.nameExist
String? errorMessage = status == 402
? _subtitle?.nameExist
: status == 401
? _subtitle.emailExist
? _subtitle?.emailExist
: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
content: Text(errorMessage??""),
));
}
},

@ -5,14 +5,14 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/notification/notification_manger.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/app_notification.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/pages/user/land_page.dart';
import '../../controllers/notification/notification_manger.dart';
import '../../controllers/providers/api/user_provider.dart';
import '../../controllers/providers/settings/setting_provider.dart';
import '../../models/app_notification.dart';
import '../../models/user.dart';
import 'login.dart';
import 'user/land_page.dart';
class SplashScreen extends StatefulWidget {
static const String routeName = '/splashScreen';
@ -24,11 +24,11 @@ class SplashScreen extends StatefulWidget {
}
class _SplashScreenState extends State<SplashScreen> {
SettingProvider _settingProvider;
UserProvider _userProvider;
SettingProvider? _settingProvider;
UserProvider? _userProvider;
_goToUserScreen(User user) {
_userProvider.user = user;
_goToUserScreen(User? user) {
_userProvider?.user = user;
// Navigator.of(context).pushNamed(Login.id);
Navigator.of(context).pushNamed(LandPage.id);
}
@ -39,9 +39,9 @@ class _SplashScreenState extends State<SplashScreen> {
NotificationManger.initialisation((notificationDetails) {
AppNotification notification =
AppNotification.fromJson(json.decode(notificationDetails.payload));
if (notification.path == null || notification.path.isEmpty) return;
Navigator.pushNamed(context, notification.path,
AppNotification.fromJson(json.decode(notificationDetails.payload??""));
if (notification.path == null || (notification.path?.isEmpty??false)) return;
Navigator.pushNamed(context, notification.path??"",
arguments: notification.requestId);
}, (id, title, body, payload) async {});
super.initState();
@ -63,8 +63,8 @@ class _SplashScreenState extends State<SplashScreen> {
callback: (animation) async {
print(await FirebaseMessaging.instance.getToken());
Navigator.of(context).pushNamed(Login.id);
if (_settingProvider.isLoaded && _settingProvider.user != null) {
_goToUserScreen(_settingProvider.user);
if ((_settingProvider?.isLoaded??false) && _settingProvider?.user != null) {
_goToUserScreen(_settingProvider?.user);
}
},
),

@ -1,29 +1,30 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/gas_refill_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_update_details_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/gas_refill_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../models/enums/user_types.dart';
import '../../../../models/gas_refill/gas_refill_model.dart';
import '../../../../models/subtitle.dart';
import '../../../../models/user.dart';
import '../../../app_style/colors.dart';
import '../../../app_style/sizing.dart';
import '../../../widgets/buttons/app_back_button.dart';
import '../../../widgets/buttons/app_button.dart';
import '../../../widgets/buttons/app_icon_button.dart';
import '../../../widgets/gas_refill/gas_refill_update_details_item.dart';
import '../../../widgets/loaders/loading_manager.dart';
import '../../../widgets/requests/info_row.dart';
import '../../../widgets/requests/request_status.dart';
import '../../../widgets/status/gas_refill/gas_status.dart';
import '../../../widgets/titles/app_sub_title.dart';
class GasRefillDetails extends StatefulWidget {
final GasRefillModel model;
const GasRefillDetails({Key key, this.model}) : super(key: key);
final GasRefillModel? model;
const GasRefillDetails({Key? key, this.model}) : super(key: key);
@override
State<GasRefillDetails> createState() => _GasRefillDetailsState();
@ -34,34 +35,34 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
final GasRefillModel _model = GasRefillModel();
bool _enableEdit = false;
bool _validate = false;
UserProvider _userProvider;
SettingProvider _settingProvider;
GasRefillProvider _gasRefillProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
GasRefillProvider? _gasRefillProvider;
bool _isLoading = false;
Subtitle _subtitle;
Subtitle? _subtitle;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
_update() async {
_validate = true;
if(!_formKey.currentState.validate()){
if(!(_formKey.currentState?.validate()??false)){
setState(() {});
return false;
}
_formKey.currentState.save();
_formKey.currentState?.save();
_isLoading =true;
setState(() {});
int status = await _gasRefillProvider.updateModel(
user: _userProvider.user,
host: _settingProvider.host,
int? status = await _gasRefillProvider?.updateModel(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
newModel: _model,
oldModel: widget.model
);
_isLoading =false;
setState(() {});
if(status >= 200 && status < 300){
if(status != null && status >= 200 && status < 300){
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
msg: _subtitle?.requestCompleteSuccessfully??"",
);
_enableEdit = false;
_validate = false;
@ -81,13 +82,13 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
@override
void initState() {
_model.fromGasRefillModel(widget.model);
_model.fromGasRefillModel(widget.model??GasRefillModel());
super.initState();
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context);
@ -108,19 +109,19 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4),
child: Row(
children: [
const ABackButton(),
ABackButton(),
Expanded(
child: Center(
child: Text(
_subtitle.details,
style: Theme.of(context).textTheme.headline6.copyWith(
_subtitle?.details??"",
style: Theme.of(context).textTheme.headline6?.copyWith(
color: AColors.white,
fontStyle: FontStyle.italic
),
),
),
),
if(_userProvider.user.type == UsersTypes.engineer)
if(_userProvider?.user?.type == UsersTypes.engineer)
AIconButton(
iconData: _enableEdit ? Icons.cancel : Icons.edit,
color: Theme.of(context).colorScheme.onPrimary,
@ -128,7 +129,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
backgroundColor: AColors.green,
onPressed: () async {
_enableEdit = !_enableEdit;
_model.fromGasRefillModel(widget.model);
_model.fromGasRefillModel(widget.model??GasRefillModel());
setState(() {});
},
),
@ -143,21 +144,21 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RequestInfoRow(
title: _subtitle.title,
info: _model.title,
title: _subtitle?.title??"",
info: _model.title??"",
),
RequestInfoRow(
title: _subtitle.hospital,
info: _model.clientName,
title: _subtitle?.hospital??"",
info: _model.clientName??"",
),
_enableEdit ?
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8,),
ASubTitle(_subtitle.status),
ASubTitle(_subtitle?.status??""),
if(_validate && _model.status == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,),
const SizedBox(height: 4,),
GasStatusMenu(
initialValue: _model.status,
@ -171,13 +172,13 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
children: [
Expanded(
child: Text(
"${_subtitle.status} : ",
"${_subtitle?.status} : ",
style: Theme.of(context).textTheme.subtitle2,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
StatusLabel(label: _model.status.label,
color: AColors.getGasStatusColor(_model.status.id)
StatusLabel(label: _model.status?.label??"",
color: AColors.getGasStatusColor(_model.status?.id??0)
),
],
),
@ -187,9 +188,9 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: _model.details.length,
itemCount: _model.details?.length,
itemBuilder: (context,index){
final details = _model.details[index];
final details = _model.details![index];
return GasRefillUpdateDetailsItem(
details: details,
validate: _validate,
@ -202,7 +203,7 @@ class _GasRefillDetailsState extends State<GasRefillDetails> {
children: [
const SizedBox(height: 16,),
AButton(
text: _subtitle.update,
text: _subtitle?.update??"",
onPressed: _update,
),
],

@ -1,28 +1,27 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/gas_refill_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_create_details_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_cylinder_size.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart';
import 'package:test_sa/views/widgets/status/gas_refill/gas_type.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/gas_refill_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/validator/validator.dart';
import '../../../../models/gas_refill/gas_refill_details.dart';
import '../../../../models/gas_refill/gas_refill_model.dart';
import '../../../../models/subtitle.dart';
import '../../../../models/user.dart';
import '../../../app_style/sizing.dart';
import '../../../widgets/app_text_form_field.dart';
import '../../../widgets/buttons/app_button.dart';
import '../../../widgets/gas_refill/gas_refill_create_details_item.dart';
import '../../../widgets/loaders/loading_manager.dart';
import '../../../widgets/status/gas_refill/gas_type.dart';
import '../../../widgets/titles/app_sub_title.dart';
class RequestGasRefill extends StatefulWidget {
static const String id = "/request-gas-refill";
const RequestGasRefill({Key key}) : super(key: key);
const RequestGasRefill({Key? key}) : super(key: key);
@override
State<RequestGasRefill> createState() => _RequestGasRefillState();
@ -31,11 +30,11 @@ class RequestGasRefill extends StatefulWidget {
class _RequestGasRefillState extends State<RequestGasRefill> {
bool _isLoading = false;
bool _validate = false;
Subtitle _subtitle;
UserProvider _userProvider;
SettingProvider _settingProvider;
GasRefillProvider _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails();
Subtitle? _subtitle;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
GasRefillProvider? _gasRefillProvider;
GasRefillDetails _currentDetails = GasRefillDetails(model: null);
final TextEditingController _requestedQuantityController = TextEditingController();
final GasRefillModel _formModel = GasRefillModel(details: []);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@ -48,23 +47,23 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
}
_onSubmit() async {
if(_formModel.details.isEmpty){
if((_formModel.details?.isEmpty??false)){
if(!_addNewModel()) return;
}
_isLoading =true;
setState(() {});
int status = await _gasRefillProvider.createModel(
user: _userProvider.user,
host: _settingProvider.host,
int? status = await _gasRefillProvider?.createModel(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
model: _formModel,
);
_isLoading =false;
setState(() {});
if(status >= 200 && status < 300){
if(status != null && status >= 200 && status < 300){
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
msg: _subtitle?.requestCompleteSuccessfully??"",
);
Navigator.of(context).pop();
}else{
@ -82,22 +81,22 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
bool _addNewModel(){
_validate = true;
if(!_formKey.currentState.validate()){
if(!(_formKey.currentState?.validate()??false)){
setState(() {});
return false;
}
_formKey.currentState.save();
_formKey.currentState?.save();
if(!_currentDetails.validate()) {
setState(() { });
return false;
}
_formModel.details.insert(0,_currentDetails);
_formModel.details?.insert(0,_currentDetails);
_validate = false;
Scrollable.ensureVisible(_DetailsKey.currentContext);
_requestedQuantityController.clear();
_currentDetails = GasRefillDetails();
_currentDetails = GasRefillDetails(model: null);
setState(() {});
return true;
}
@ -109,7 +108,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_gasRefillProvider = Provider.of<GasRefillProvider>(context,listen: false);
@ -133,7 +132,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
padding: const EdgeInsets.all(8.0),
child: Text(
"Request Gas Refill",
style: Theme.of(context).textTheme.headline5.copyWith(
style: Theme.of(context).textTheme.headline5?.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 28,
fontWeight: FontWeight.bold
@ -171,7 +170,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
const SizedBox(height: 4,),
const ASubTitle("Type"),
if(_validate && _currentDetails.type == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,),
const SizedBox(height: 4,),
GasTypeMenu(
initialValue: _currentDetails.type,
@ -192,9 +191,9 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
// },
// ),
const SizedBox(height: 8,),
ASubTitle(_subtitle.quantity),
ASubTitle(_subtitle?.quantity??""),
if(_validate && _currentDetails.requestedQuantity == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,),
SizedBox(height: 4,),
ATextFormField(
initialValue: (_currentDetails?.requestedQuantity ?? "").toString(),
@ -211,22 +210,22 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
),
const SizedBox(height: 16),
AButton(
text: _subtitle.add,
text: _subtitle?.add??"",
onPressed: _addNewModel,
),
if(_formModel.details.isNotEmpty)
if((_formModel.details?.isNotEmpty??false))
const ASubTitle("Gas Requests"),
ListView.builder(
key: _DetailsKey,
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: _formModel.details.length,
itemCount: _formModel.details?.length,
itemBuilder: (context,index){
final model = _formModel.details[index];
final model = _formModel.details![index];
return GasRefillCreateDetailsItem(
model: model,
onDelete: (){
_formModel.details.remove(model);
_formModel.details?.remove(model);
setState(() {});
},
);
@ -234,7 +233,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
),
const SizedBox(height: 16),
AButton(
text: _subtitle.submit,
text: _subtitle?.submit??"",
onPressed: _onSubmit,
),
const SizedBox(height: 100,)

@ -1,18 +1,21 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/gas_refill_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_list.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/gas_refill_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../models/subtitle.dart';
import '../../../../models/user.dart';
import '../../../app_style/colors.dart';
import '../../../widgets/buttons/app_back_button.dart';
import '../../../widgets/gas_refill/gas_refill_list.dart';
import '../../../widgets/loaders/loading_manager.dart';
class TrackGasRefillPage extends StatefulWidget {
static const String id = "/track-gas-refill";
const TrackGasRefillPage({Key key}) : super(key: key);
const TrackGasRefillPage({Key? key}) : super(key: key);
@override
State<TrackGasRefillPage> createState() => _TrackGasRefillPageState();
@ -20,27 +23,27 @@ class TrackGasRefillPage extends StatefulWidget {
class _TrackGasRefillPageState extends State<TrackGasRefillPage>
with TickerProviderStateMixin{
GasRefillProvider _gasRefillProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
GasRefillProvider? _gasRefillProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
@override
Widget build(BuildContext context) {
_gasRefillProvider = Provider.of<GasRefillProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
body: SafeArea(
child: LoadingManager(
isLoading: _gasRefillProvider.isLoading,
isFailedLoading: _gasRefillProvider.items == null,
stateCode: _gasRefillProvider.stateCode,
isLoading: _gasRefillProvider?.isLoading??false,
isFailedLoading: _gasRefillProvider?.items == null,
stateCode: _gasRefillProvider?.stateCode??0,
onRefresh: () async {
_gasRefillProvider.reset();
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
_gasRefillProvider?.reset();
await _gasRefillProvider?.getRequests(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
);
},
child: Stack(
@ -58,8 +61,8 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
Expanded(
child: Center(
child: Text(
_subtitle.serviceRequests,
style: Theme.of(context).textTheme.headline6.copyWith(
_subtitle?.serviceRequests??"",
style: Theme.of(context).textTheme.headline6?.copyWith(
color: AColors.grey3A,
fontStyle: FontStyle.italic
),
@ -75,14 +78,14 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
),
Expanded(
child: GasRefillList(
nextPage: _gasRefillProvider.nextPage,
nextPage: _gasRefillProvider?.nextPage??false,
onLazyLoad: () async {
await _gasRefillProvider.getRequests(
user: _userProvider.user,
host: _settingProvider.host,
await _gasRefillProvider?.getRequests(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
);
},
items: _gasRefillProvider.items,
items: _gasRefillProvider?.items??[],
),
),
],

@ -1,34 +1,37 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/app_notification.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/pages/user/requests/future_request_service_details.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import 'package:test_sa/views/widgets/notifications/notification_item.dart';
import 'package:flutter/material.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../models/app_notification.dart';
import '../../../../models/subtitle.dart';
import '../../../widgets/loaders/lazy_loading.dart';
import '../../../widgets/loaders/no_item_found.dart';
import '../../../widgets/notifications/notification_item.dart';
import '../requests/future_request_service_details.dart';
class NotificationsList extends StatelessWidget {
final List<AppNotification> notifications;
final bool nextPage;
final Future<void> Function() onLazyLoad;
final List<AppNotification>? notifications;
final bool? nextPage;
final Future<void> Function()? onLazyLoad;
const NotificationsList({Key key, this.notifications, this.nextPage, this.onLazyLoad}) : super(key: key);
const NotificationsList({Key? key, this.notifications, this.nextPage, this.onLazyLoad}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(notifications.length == 0){
return NoItemFound(message: _subtitle.notificationsNotFound,);
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
if((notifications?.isEmpty??false)){
return NoItemFound(message: _subtitle?.notificationsNotFound??"",);
}
return LazyLoading(
nextPage: nextPage,
onLazyLoad: onLazyLoad,
nextPage: nextPage??false,
onLazyLoad: onLazyLoad??()async{},
onLoadingEnd: () { },
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: notifications.length,
itemCount: notifications?.length,
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 8),
itemBuilder: (context,itemIndex){
return NotificationItem(
notification: notifications[itemIndex],
notification: notifications![itemIndex],
onPressed: (notification){
Navigator.of(context).pushNamed(
FutureRequestServiceDetails.id,

@ -1,14 +1,17 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/notifications_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/pages/user/notifications/notifications_list.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/notifications_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../models/subtitle.dart';
import '../../../../models/user.dart';
import '../../../app_style/colors.dart';
import '../../../widgets/buttons/app_back_button.dart';
import '../../../widgets/loaders/loading_manager.dart';
import 'notifications_list.dart';
class NotificationsPage extends StatefulWidget {
static final String id = "/notifications";
@override
@ -17,28 +20,28 @@ class NotificationsPage extends StatefulWidget {
class _NotificationsPageState extends State<NotificationsPage>
with TickerProviderStateMixin{
NotificationsProvider _notificationsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
Subtitle _subtitle;
NotificationsProvider? _notificationsProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
Subtitle? _subtitle;
@override
Widget build(BuildContext context) {
_notificationsProvider = Provider.of<NotificationsProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
body: SafeArea(
child: LoadingManager(
isLoading: _notificationsProvider.isLoading,
isFailedLoading: _notificationsProvider.notifications == null,
stateCode: _notificationsProvider.stateCode,
isLoading: _notificationsProvider?.isLoading??false,
isFailedLoading: _notificationsProvider?.notifications == null,
stateCode: _notificationsProvider?.stateCode??0,
onRefresh: () async {
_notificationsProvider.reset();
await _notificationsProvider.getNotifications(
user: _userProvider.user,
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id,
_notificationsProvider?.reset();
await _notificationsProvider?.getNotifications(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
hospitalId: _userProvider?.user?.hospital?.id??"",
);
},
child: Stack(
@ -56,8 +59,8 @@ class _NotificationsPageState extends State<NotificationsPage>
Expanded(
child: Center(
child: Text(
_subtitle.notifications,
style: Theme.of(context).textTheme.headline6.copyWith(
_subtitle?.notifications??"",
style: Theme.of(context).textTheme.headline6?.copyWith(
color: AColors.white,
fontStyle: FontStyle.italic
),
@ -73,15 +76,15 @@ class _NotificationsPageState extends State<NotificationsPage>
),
Expanded(
child: NotificationsList(
nextPage: _notificationsProvider.nextPage,
nextPage: _notificationsProvider?.nextPage,
onLazyLoad: () async {
await _notificationsProvider.getNotifications(
user: _userProvider.user,
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id,
await _notificationsProvider?.getNotifications(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
hospitalId: _userProvider?.user?.hospital?.id??"",
);
},
notifications: _notificationsProvider.notifications,
notifications: _notificationsProvider?.notifications,
),
),
],

@ -1,47 +1,40 @@
import 'dart:convert';
import 'dart:io';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart';
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart';
import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart';
import 'package:test_sa/views/widgets/status/report/service_report_status.dart';
import 'package:test_sa/views/widgets/status/report/service_report_type.dart';
import 'package:test_sa/views/widgets/status/report/service_status.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import '../../../../../controllers/localization/localization.dart';
import '../../../../../controllers/providers/api/service_requests_provider.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../controllers/providers/api/user_provider.dart';
import '../../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../../controllers/validator/validator.dart';
import '../../../../../models/device/device.dart';
import '../../../../../models/lookup.dart';
import '../../../../../models/service_report.dart';
import '../../../../../models/service_request/service_request.dart';
import '../../../../../models/subtitle.dart';
import '../../../../app_style/colors.dart';
import '../../../../app_style/sizing.dart';
import '../../../../widgets/app_text_form_field.dart';
import '../../../../widgets/date_and_time/date_picker.dart';
import '../../../../widgets/equipment/auto_complete_devices_field.dart';
import '../../../../widgets/images/mini_one_image_picker.dart';
import '../../../../widgets/loaders/loading_manager.dart';
import '../../../../widgets/speech_to_text/speech_to_text.dart';
import '../../../../widgets/status/report/service_report_last_call.dart';
import '../../../../widgets/status/report/service_report_reasons.dart';
import '../../../../widgets/status/report/service_report_status.dart';
import '../../../../widgets/status/report/service_status.dart';
import '../../../../widgets/titles/app_sub_title.dart';
class CreateServiceReport extends StatefulWidget {
static final String id = "/create-service-report";
final ServiceRequest request ;
final ServiceRequest? request ;
const CreateServiceReport({Key key, this.request}) : super(key: key);
const CreateServiceReport({Key? key, this.request}) : super(key: key);
@override
_CreateServiceReportState createState() => _CreateServiceReportState();
}
@ -49,16 +42,16 @@ class CreateServiceReport extends StatefulWidget {
class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin{
UserProvider _userProvider;
SettingProvider _settingProvider;
ServiceRequestsProvider _serviceRequestsProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
ServiceRequestsProvider? _serviceRequestsProvider;
bool _validate = false;
ServiceReport _serviceReport;
ServiceReport? _serviceReport;
bool _isLoading = false;
Subtitle _subtitle;
File _image;
Subtitle? _subtitle;
File? _image;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _faultController = TextEditingController();
@ -70,8 +63,8 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
visitDate: DateTime.now(),
type: const Lookup(id: 2),
device: Device(
id: widget.request.deviceId,
serialNumber: widget.request.deviceSerialNumber,
id: widget.request?.deviceId,
serialNumber: widget.request?.deviceSerialNumber,
),
parts: []
);
@ -89,7 +82,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
@ -110,8 +103,8 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
_subtitle.newServiceReport,
style: Theme.of(context).textTheme.headline5.copyWith(
_subtitle?.newServiceReport??"",
style: Theme.of(context).textTheme.headline5?.copyWith(
color: AColors.cyan,
fontSize: 28,
fontWeight: FontWeight.bold
@ -139,12 +132,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
Wrap(
spacing: 10,
children: [
ASubTitle("${_subtitle.callId}: ${widget.request.requestCode}",font: 14,),
widget.request.deviceSerialNumber == null ? const SizedBox():
ASubTitle("${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",font: 14,),
ASubTitle("${_subtitle?.callId}: ${widget.request?.requestCode}",font: 14,),
widget.request?.deviceSerialNumber == null ? const SizedBox():
ASubTitle("${_subtitle?.deviceSN}: ${widget.request?.deviceSerialNumber}",font: 14,),
Text(
"${_subtitle.customer}: ${widget.request.hospitalName}",
style: Theme.of(context).textTheme.subtitle1.copyWith(
"${_subtitle?.customer}: ${widget.request?.hospitalName}",
style: Theme.of(context).textTheme.subtitle1?.copyWith(
fontWeight: FontWeight.bold,
fontSize: 12,
),
@ -183,19 +176,19 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.visitDate),
_validate && _serviceReport.visitDate == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
ASubTitle(_subtitle?.visitDate??""),
_validate && _serviceReport?.visitDate == null ?
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,):
const SizedBox.shrink(),
Row(
children: [
Expanded(
child: ADatePicker(
date: _serviceReport.visitDate,
date: _serviceReport?.visitDate??DateTime.now(),
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date){
_serviceReport.visitDate = date;
_serviceReport?.visitDate = date;
setState(() {});
},
),
@ -211,19 +204,19 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
const SizedBox(height: 8,),
// device sn
Visibility(
visible: widget.request.deviceSerialNumber == null,
visible: widget.request?.deviceSerialNumber == null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.deviceSN),
_validate && _serviceReport.device?.id == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
ASubTitle(_subtitle?.deviceSN??""),
_validate && _serviceReport?.device?.id == null ?
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,):
const SizedBox.shrink(),
AutoCompleteDeviceField(
hospitalId: widget.request.hospitalId,
initialValue: _serviceReport.device,
hospitalId: widget.request?.hospitalId??"",
initialValue: _serviceReport?.device,
onPick: (id){
_serviceReport.device.id = id;
_serviceReport?.device?.id = id;
},
),
const SizedBox(height: 8,),
@ -231,15 +224,15 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
),
const SizedBox(height: 8,),
ASubTitle(_subtitle.serviceType),
_validate && _serviceReport.serviceType == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
ASubTitle(_subtitle?.serviceType??""),
_validate && _serviceReport?.serviceType == null ?
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,):
const SizedBox.shrink(),
const SizedBox(height: 4,),
ServiceStatusMenu(
initialValue: _serviceReport.serviceType,
initialValue: _serviceReport?.serviceType,
onSelect: (status){
_serviceReport.serviceType = status;
_serviceReport?.serviceType = status;
},
),
const SizedBox(height: 8,),
@ -251,15 +244,15 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.reportStatus),
_validate && _serviceReport.status == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
ASubTitle(_subtitle?.reportStatus??""),
_validate && _serviceReport?.status == null ?
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,):
const SizedBox.shrink(),
const SizedBox(height: 4,),
ServiceReportStatusMenu(
report: _serviceReport,
onSelect: (status){
_serviceReport.status = status;
_serviceReport?.status = status;
},
),
],
@ -274,20 +267,20 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.callLastSituation),
_validate && _serviceReport.callLastSituation == null ?
ASubTitle(_subtitle.requiredWord,color: Colors.red,):
ASubTitle(_subtitle?.callLastSituation??""),
_validate && _serviceReport?.callLastSituation == null ?
ASubTitle(_subtitle?.requiredWord??"",color: Colors.red,):
const SizedBox.shrink(),
const SizedBox(height: 4,),
ServiceReportLastCallsMenu(
report: _serviceReport,
onSelect: (status){
if(status?.id == 12
|| _serviceReport.callLastSituation?.id == 12){
_serviceReport.callLastSituation = status;
|| _serviceReport?.callLastSituation?.id == 12){
_serviceReport?.callLastSituation = status;
setState(() {});
} else {
_serviceReport.callLastSituation = status;
_serviceReport?.callLastSituation = status;
}
},
),
@ -298,25 +291,25 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
const SizedBox(height: 8,),
// invoice number & code
_serviceReport.callLastSituation?.id != 12 ? const SizedBox.shrink():
_serviceReport?.callLastSituation?.id != 12 ? const SizedBox.shrink():
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.invoiceNumber),
ASubTitle(_subtitle?.invoiceNumber??""),
const SizedBox(height: 8,),
ATextFormField(
initialValue: _serviceReport?.invoiceNumber,
initialValue: _serviceReport?.invoiceNumber??"",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.hasValue(value)
? null : _subtitle.requiredWord,
? null : _subtitle?.requiredWord,
textInputType: TextInputType.number,
onSaved: (value){
_serviceReport.invoiceNumber = value;
_serviceReport?.invoiceNumber = value;
},
),
],
@ -327,18 +320,18 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.invoiceCode),
ASubTitle(_subtitle?.invoiceCode??""),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _serviceReport?.invoiceCode,
initialValue: _serviceReport?.invoiceCode??"",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.hasValue(value)
? null : _subtitle.requiredWord,
? null : _subtitle?.requiredWord,
textInputType: TextInputType.text,
onSaved: (value){
_serviceReport.invoiceCode = value;
_serviceReport?.invoiceCode = value;
},
),
],
@ -350,7 +343,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
const SizedBox(height: 8,),
Row(
children: [
ASubTitle(_subtitle.faultDescription),
ASubTitle(_subtitle?.faultDescription??""),
Expanded(
child: SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
@ -364,22 +357,22 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _serviceReport?.faultDescription,
initialValue: _serviceReport?.faultDescription??"",
textAlign: TextAlign.center,
controller: _faultController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.hasValue(value)
? null : _subtitle.requiredWord,
? null : _subtitle?.requiredWord,
textInputType: TextInputType.multiline,
onSaved: (value){
_serviceReport.faultDescription = value;
_serviceReport?.faultDescription = value;
},
),
const SizedBox(height: 8,),
Row(
children: [
ASubTitle(_subtitle.workPreformed),
ASubTitle(_subtitle?.workPreformed??""),
Expanded(
child: SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
@ -393,16 +386,16 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
const SizedBox(height: 4,),
ATextFormField(
initialValue: _serviceReport?.workPreformed,
initialValue: _serviceReport?.workPreformed??"",
textAlign: TextAlign.center,
controller: _workPreformedController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) =>
Validator.hasValue(value)
? null : _subtitle.requiredWord,
? null : _subtitle?.requiredWord,
textInputType: TextInputType.multiline,
onSaved: (value){
_serviceReport.workPreformed = value;
_serviceReport?.workPreformed = value;
},
),
const SizedBox(height: 8,),
@ -415,12 +408,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.reasons),
ASubTitle(_subtitle?.reasons??""),
const SizedBox(height: 4,),
ServiceReportReasonsMenu(
initialValue: _serviceReport.reason,
initialValue: _serviceReport?.reason,
onSelect: (status){
_serviceReport.reason = status;
_serviceReport?.reason = status;
},
),
],
@ -431,13 +424,13 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.attachImage),
ASubTitle(_subtitle?.attachImage??""),
AMiniOneImagePicker(
//error: _validate && _serviceReport.image == null,
image: _image,
onPick: (image){
_image =image;
_serviceReport.image = base64Encode(image.readAsBytesSync());
_serviceReport?.image = base64Encode(image.readAsBytesSync());
},
),
],

@ -11,7 +11,7 @@ class ATextFormField extends StatefulWidget {
final String labelText;
final TextInputType textInputType;
final String initialValue;
final TextStyle style;
final TextStyle? style;
final bool enable;
final TextAlign textAlign;
final FocusNode node;

@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import '../../app_style/colors.dart';
import 'app_icon_button.dart';
class ABackButton extends StatelessWidget {
final VoidCallback onPressed;
final IconData icon;
final VoidCallback? onPressed;
final IconData? icon;
const ABackButton({Key key, this.onPressed,this.icon}) : super(key: key);
const ABackButton({Key? key, this.onPressed, this.icon}) : super(key: key);
@override
Widget build(BuildContext context) {

@ -1,16 +1,17 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class AButton extends StatelessWidget {
final String text;
final Color color;
final EdgeInsets padding;
final EdgeInsets? padding;
final TextStyle textStyle;
final VoidCallback onPressed;
final TextStyle? textStyle;
final VoidCallback? onPressed;
const AButton({Key key, this.color = AColors.primaryColor, this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
const AButton({Key? key, this.color = AColors.primaryColor, required this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -27,7 +28,7 @@ class AButton extends StatelessWidget {
onPressed: onPressed,
child: Text(
text ?? "",
style: textStyle ?? Theme.of(context).textTheme.subtitle2.copyWith(color: AColors.white, fontSize: 14,fontWeight: FontWeight.w600),
style: textStyle ?? Theme.of(context).textTheme.subtitle2?.copyWith(color: AColors.white, fontSize: 14,fontWeight: FontWeight.w600),
textScaleFactor: AppStyle.getScaleFactor(context),
),
),

@ -1,14 +1,15 @@
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
import '../../app_style/sizing.dart';
class AFlatButton extends StatelessWidget {
final String text;
final Color textColor;
final TextStyle style;
final EdgeInsets padding;
final VoidCallback onPressed;
final Color? textColor;
final TextStyle? style;
final EdgeInsets? padding;
final VoidCallback? onPressed;
const AFlatButton({Key key, this.text, this.textColor,this.style ,this.onPressed,this.padding}) : super(key: key);
const AFlatButton({Key? key, required this.text, this.textColor,this.style ,this.onPressed, this.padding}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextButton(

@ -1,20 +1,22 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class AIconButton extends StatelessWidget {
final IconData iconData;
final Color color;
final Color backgroundColor;
final VoidCallback onPressed;
final double iconSize;
final Color? color;
final Color? backgroundColor;
final VoidCallback? onPressed;
final double? iconSize;
final double buttonSize;
const AIconButton({
Key key,
this.iconData,
Key? key,
required this.iconData,
this.onPressed,
this.color,
this.iconSize,

@ -1,15 +1,16 @@
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../../app_style/sizing.dart';
class AIconButton2 extends StatelessWidget {
final IconData iconData;
final Color color;
final VoidCallback onPressed;
final Color? color;
final VoidCallback? onPressed;
const AIconButton2({
Key key,
this.iconData,
Key? key,
required this.iconData,
this.onPressed,
this.color,
}) : super(key: key);

@ -1,15 +1,16 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class AOutLinedButton extends StatelessWidget {
final String text;
final Color color;
final EdgeInsets padding;
final TextStyle textStyle;
final VoidCallback onPressed;
final Color? color;
final EdgeInsets? padding;
final TextStyle? textStyle;
final VoidCallback? onPressed;
const AOutLinedButton({Key key, this.color = AColors.primaryColor, this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
const AOutLinedButton({Key? key, this.color = AColors.primaryColor, required this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -20,7 +21,7 @@ class AOutLinedButton extends StatelessWidget {
.of(context)
.textTheme
.subtitle2
.copyWith(fontSize: 18),
?.copyWith(fontSize: 18),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context))),
),
onPressed: onPressed,
@ -33,7 +34,7 @@ class AOutLinedButton extends StatelessWidget {
.of(context)
.textTheme
.subtitle2
.copyWith(color: AColors.primaryColor, fontSize: 14, fontWeight: FontWeight.w600),
?.copyWith(color: AColors.primaryColor, fontSize: 14, fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
textScaleFactor: AppStyle.getScaleFactor(context),
),

@ -1,14 +1,15 @@
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
import '../../app_style/sizing.dart';
class ASmallButton extends StatelessWidget {
final String text;
final TextStyle style;
final Color color;
final EdgeInsets padding;
final VoidCallback onPressed;
final TextStyle? style;
final Color? color;
final EdgeInsets? padding;
final VoidCallback? onPressed;
const ASmallButton({Key key, this.text, this.style ,this.onPressed,this.padding, this.color}) : super(key: key);
const ASmallButton({Key? key, required this.text, this.style ,this.onPressed,this.padding, this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
@ -21,7 +22,7 @@ class ASmallButton extends StatelessWidget {
),
child: Text(
text??"",
style: style ?? Theme.of(context).textTheme.bodyText1.copyWith(
style: style ?? Theme.of(context).textTheme.bodyText1?.copyWith(
color: color == Colors.white
? Theme.of(context).primaryColor : Colors.white
),

@ -1,13 +1,14 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/sizing.dart';
class ADatePicker extends StatelessWidget {
final DateTime date;
final DateTime from;
final DateTime to;
final Function(DateTime) onDatePicker;
final DateTime? date;
final DateTime? from;
final DateTime? to;
final Function(DateTime)? onDatePicker;
const ADatePicker({Key key, this.date, this.onDatePicker, this.from, this.to}) : super(key: key);
const ADatePicker({Key? key, this.date, this.onDatePicker, this.from, this.to}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -28,13 +29,13 @@ class ADatePicker extends StatelessWidget {
textScaleFactor: AppStyle.getScaleFactor(context),
),
onPressed: () async {
DateTime picked = await showDatePicker(
DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: from ?? DateTime.now(),
lastDate: to ?? DateTime.now().add(Duration(days: 365))
);
onDatePicker(picked);
onDatePicker!(picked!);
},
);
}

@ -1,23 +1,23 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart';
import '../../app_style/sizing.dart';
import 'date_picker.dart';
class FromToDateBar extends StatefulWidget {
final DateTime from;
final DateTime to;
final Function(DateTime) onPickFrom;
final Function(DateTime) onPickTo;
final Function(DateTime)? onPickFrom;
final Function(DateTime)? onPickTo;
const FromToDateBar({Key key, this.from, this.to, this.onPickFrom, this.onPickTo}) : super(key: key);
const FromToDateBar({Key? key, required this.from, required this.to, this.onPickFrom, this.onPickTo}) : super(key: key);
@override
_FromToDateBarState createState() => _FromToDateBarState();
}
class _FromToDateBarState extends State<FromToDateBar> {
DateTime _from;
DateTime _to;
late DateTime _from;
late DateTime _to;
@override
void initState() {
@ -28,7 +28,7 @@ class _FromToDateBarState extends State<FromToDateBar> {
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
@ -37,8 +37,8 @@ class _FromToDateBarState extends State<FromToDateBar> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_subtitle.from,
style: Theme.of(context).textTheme.bodyText1.copyWith(
_subtitle?.from??'',
style: Theme.of(context).textTheme.bodyText1?.copyWith(
fontSize: 12,
fontWeight: FontWeight.normal
),
@ -50,7 +50,7 @@ class _FromToDateBarState extends State<FromToDateBar> {
onDatePicker: (date){
_from = date;
setState(() {});
widget.onPickFrom(date);
widget.onPickFrom!(date);
},
),
],
@ -59,8 +59,8 @@ class _FromToDateBarState extends State<FromToDateBar> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_subtitle.to,
style: Theme.of(context).textTheme.bodyText1.copyWith(
_subtitle?.to??"",
style: Theme.of(context).textTheme.bodyText1?.copyWith(
fontSize: 12,
fontWeight: FontWeight.normal
),
@ -72,7 +72,7 @@ class _FromToDateBarState extends State<FromToDateBar> {
onDatePicker: (date){
_to = date;
setState(() {});
widget.onPickTo(date);
widget.onPickTo!(date);
},
),
],

@ -1,20 +1,21 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/departments/single_department_picker.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/department.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import 'single_department_picker.dart';
class DepartmentButton extends StatelessWidget {
final Function(Department) onDepartmentPick;
final Department department;
final Function(Department)? onDepartmentPick;
final Department? department;
const DepartmentButton({Key key, this.department, this.onDepartmentPick}) : super(key: key);
const DepartmentButton({Key? key, this.department, this.onDepartmentPick}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
@ -31,7 +32,7 @@ class DepartmentButton extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
department?.name ?? _subtitle.pickUnite,
department?.name ?? _subtitle?.pickUnite??"",
style: Theme.of(context).textTheme.bodyText1,
textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
@ -44,7 +45,7 @@ class DepartmentButton extends StatelessWidget {
),
onPressed: () async {
Department _department = await Navigator.of(context).pushNamed(SingleDepartmentPicker.id) as Department;
onDepartmentPick(_department);
onDepartmentPick!(_department);
});
}
}

@ -1,12 +1,14 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../models/department.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class DepartmentItem extends StatelessWidget {
final Department department;
final Function(Department) onPressed;
final Department? department;
final Function(Department)? onPressed;
const DepartmentItem({Key key, this.department, this.onPressed}) : super(key: key);
const DepartmentItem({Key? key, this.department, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
@ -21,12 +23,12 @@ class DepartmentItem extends StatelessWidget {
),
),
onPressed: (){
onPressed(department);
onPressed!(department!);
},
child: ListTile(
title: Text(
department.name ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
department?.name ?? "",
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white
),
textDirection: TextDirection.rtl,

@ -1,15 +1,15 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/departments_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/departments/department_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/departments_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/department.dart';
import '../../../models/subtitle.dart';
import '../app_text_form_field.dart';
import '../loaders/loading_manager.dart';
import '../loaders/no_item_found.dart';
import 'department_item.dart';
class SingleDepartmentPicker extends StatefulWidget {
static final String id = "/single-Department-Picker";
@override
@ -17,30 +17,30 @@ class SingleDepartmentPicker extends StatefulWidget {
}
class _SingleDepartmentPickerState extends State<SingleDepartmentPicker> {
DepartmentsProvider _departmentsProvider;
SettingProvider _settingProvider;
DepartmentsProvider? _departmentsProvider;
SettingProvider? _settingProvider;
List<Department> _searchableList = [];
bool _firstTime = true;
@override
Widget build(BuildContext context) {
_departmentsProvider = Provider.of<DepartmentsProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(_firstTime && _departmentsProvider.departments != null){
_searchableList.addAll(_departmentsProvider.departments);
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
if(_firstTime && _departmentsProvider?.departments != null){
_searchableList.addAll(_departmentsProvider?.departments??[]);
_firstTime = false;
}
return Scaffold(
resizeToAvoidBottomInset: false,
body: LoadingManager(
isLoading: _departmentsProvider.isLoading,
stateCode: _departmentsProvider.stateCode,
isFailedLoading: _departmentsProvider.departments == null,
isLoading: _departmentsProvider?.isLoading??false,
stateCode: _departmentsProvider?.stateCode??0,
isFailedLoading: _departmentsProvider?.departments == null,
onRefresh: () async {
_departmentsProvider.reset();
await _departmentsProvider.getDepartment(
_settingProvider.host,
_departmentsProvider?.reset();
await _departmentsProvider?.getDepartment(
_settingProvider?.host??"",
);
},
child: Column(
@ -49,15 +49,12 @@ class _SingleDepartmentPickerState extends State<SingleDepartmentPicker> {
Padding(
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
child: ATextFormField(
hintText: _subtitle.searchByName,
hintText: _subtitle?.searchByName??"",
style: Theme.of(context).textTheme.headline6,
suffixIcon: Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_departmentsProvider.departments.where(
(element) => element.name.toLowerCase().contains(
value.toLowerCase()
)
_searchableList.addAll(_departmentsProvider!.departments!.where( (element) => element.name!.toLowerCase().contains(value.toLowerCase())
).toList());
setState(() {});
},
@ -65,7 +62,7 @@ class _SingleDepartmentPickerState extends State<SingleDepartmentPicker> {
),
Expanded(
child: _searchableList.isEmpty ?
NoItemFound(message: _subtitle.noUniteFound,):
NoItemFound(message: _subtitle?.noUniteFound??"",):
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,

@ -1,58 +1,60 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/device/device_transfer_info.dart';
import '../../app_style/colors.dart';
import '../loaders/image_loader.dart';
import '../requests/info_row.dart';
import '../requests/request_status.dart';
class DeviceTransferInfoSection extends StatelessWidget {
final DeviceTransferInfo info;
final VoidCallback onEdit;
const DeviceTransferInfoSection({Key key, this.info, this.onEdit}) : super(key: key);
final VoidCallback? onEdit;
const DeviceTransferInfoSection({Key? key, required this.info, this.onEdit}) : super(key: key);
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final subtitle = AppLocalization.of(context)?.subtitle;
return Column(
children: [
RequestInfoRow(
title: subtitle.hospital,
info: info.client.name,
title: subtitle?.hospital??"",
info: info.client?.name??"",
),
RequestInfoRow(
title: subtitle.unite,
info: info.department.name,
title: subtitle?.unite??"",
info: info.department?.name??"",
),
RequestInfoRow(
title: subtitle.engineerName,
info: info.name,
title: subtitle?.engineerName??"",
info: info.name??"",
),
RequestInfoRow(
title: subtitle.workingHours,
info: info.workingHours,
title: subtitle?.workingHours??"",
info: info.workingHours??"",
),
RequestInfoRow(
title: subtitle.travelingHours,
info: info.travelingHours,
title: subtitle?.travelingHours??"",
info: info.travelingHours??"",
),
RequestInfoRow(
title: "Comment",
info: info.comment,
info: info.comment??"",
),
RequestInfoRow(
title: "Signature",
info: info.signature?.isEmpty != false
? subtitle.noDateFound : null,
contentWidget: info.signature?.isEmpty != false ? null :
info: (info.signature?.isEmpty??false) != false
? subtitle?.noDateFound??"" : "",
contentWidget: (info.signature?.isEmpty??false) != false ? Container() :
ImageLoader(
url: info.signature,
url: info.signature??"",
),
),
RequestInfoRow(
title: subtitle.status,
title: subtitle?.status??"",
infoWidget: StatusLabel(
label: info.status?.label,
color: AColors.getGasStatusColor(info.status?.id)
label: info.status?.label??"",
color: AColors.getGasStatusColor(info.status?.id??0)
),
),
],

@ -1,31 +1,26 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/user/requests/report/create_service_report.dart';
import 'package:test_sa/views/pages/user/requests/report/future_service_report.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../models/device/device_transfer.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../requests/request_status.dart';
class DeviceTransferItem extends StatelessWidget {
final int index;
final DeviceTransfer item;
final Function(DeviceTransfer) onPressed;
const DeviceTransferItem({Key key, this.item, this.onPressed, this.index}) : super(key: key);
final Function(DeviceTransfer)? onPressed;
const DeviceTransferItem({Key? key, required this.item, this.onPressed, required this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
User _user = Provider.of<UserProvider>(context,listen: false).user;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
User? _user = Provider.of<UserProvider>(context,listen: false).user;
Color itemColor = index % 2 == 0
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onPrimary;
@ -47,7 +42,7 @@ class DeviceTransferItem extends StatelessWidget {
),
//padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
onPressed: (){
onPressed(item);
onPressed!(item);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -60,7 +55,7 @@ class DeviceTransferItem extends StatelessWidget {
children: [
Text(
item.title ?? "-----",
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
color: onItemColor,
fontSize: 16,
fontWeight: FontWeight.bold
@ -71,15 +66,15 @@ class DeviceTransferItem extends StatelessWidget {
children: [
Expanded(
child: Text(
_subtitle.from,
style: Theme.of(context).textTheme.subtitle2.copyWith(
_subtitle?.from??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
),
StatusLabel(
color: AColors.getRequestStatusColor(item.sender.status?.id),
label: item.sender.status?.label,
color: AColors.getRequestStatusColor(item.sender?.status?.id??0),
label: item.sender?.status?.label??"",
)
],
@ -89,8 +84,8 @@ class DeviceTransferItem extends StatelessWidget {
children: [
Expanded(
child: Text(
item.sender.client.name,
style: Theme.of(context).textTheme.subtitle2.copyWith(
item.sender?.client?.name??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
@ -100,8 +95,8 @@ class DeviceTransferItem extends StatelessWidget {
],
),
Text(
item.sender.department.name,
style: Theme.of(context).textTheme.bodySmall.copyWith(
item.sender?.department?.name??"",
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: onItemColor,
),
),
@ -110,15 +105,15 @@ class DeviceTransferItem extends StatelessWidget {
children: [
Expanded(
child: Text(
_subtitle.to,
style: Theme.of(context).textTheme.subtitle2.copyWith(
_subtitle?.to??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
),
StatusLabel(
color: AColors.getRequestStatusColor(item.receiver.status?.id),
label: item.receiver.status?.label,
color: AColors.getRequestStatusColor(item.receiver?.status?.id??0),
label: item.receiver?.status?.label??"",
)
],
@ -128,8 +123,8 @@ class DeviceTransferItem extends StatelessWidget {
children: [
Expanded(
child: Text(
item.receiver.client.name,
style: Theme.of(context).textTheme.subtitle2.copyWith(
item.receiver?.client?.name??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
@ -139,8 +134,8 @@ class DeviceTransferItem extends StatelessWidget {
],
),
Text(
item.receiver.department.name,
style: Theme.of(context).textTheme.bodySmall.copyWith(
item.receiver?.department?.name??"",
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: onItemColor,
),
),

@ -23,8 +23,9 @@ class DeviceTransferList extends StatelessWidget {
return NoItemFound(message: subtitle?.noServiceRequestFound??"",);
}
return LazyLoading(
nextPage: nextPage,
onLazyLoad: onLazyLoad,
nextPage: nextPage??false,
onLazyLoad: onLazyLoad??()async{},
onLoadingEnd: () { },
child: ListView.builder(
//physics: const BouncingScrollPhysics(),
itemCount: items?.length,
@ -32,7 +33,7 @@ class DeviceTransferList extends StatelessWidget {
itemBuilder: (context,itemIndex){
return DeviceTransferItem(
index: itemIndex,
item: items[itemIndex],
item: items![itemIndex],
onPressed: (model){
Navigator.of(context).push(
MaterialPageRoute(

@ -1,32 +1,34 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart';
class AAlertDialog extends StatelessWidget {
final String title;
final String content;
final String? title;
final String? content;
const AAlertDialog({Key key, this.title, this.content}) : super(key: key);
const AAlertDialog({Key? key, this.title, this.content}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return CupertinoAlertDialog(
title: title != null
? Text(title)
? Text(title??"")
: null,
content: content != null
? Text(content)
? Text(content??"")
: null,
actions: <Widget>[
TextButton(
child: Text(_subtitle.confirm),
child: Text(_subtitle?.confirm??""),
onPressed: () {
Navigator.of(context).pop(true);
},
),
TextButton(
child: Text(_subtitle.cancel),
child: Text(_subtitle?.cancel??""),
onPressed: () {
Navigator.of(context).pop(false);
},

@ -1,15 +1,16 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../extensions/int_extensions.dart';
import '../../../extensions/widget_extensions.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class DrawerItem extends StatelessWidget {
final String title;
final String? title;
final IconData icon;
final VoidCallback onPressed;
final VoidCallback? onPressed;
const DrawerItem({Key key, this.title, this.icon, this.onPressed}) : super(key: key);
const DrawerItem({Key? key, this.title, required this.icon, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -28,8 +29,8 @@ class DrawerItem extends StatelessWidget {
Icon(icon, color: AColors.grey3A,size: 20),
12.width,
Text(
title,
style: Theme.of(context).textTheme.headline6.copyWith(fontSize: 14, color: AColors.grey3A),
title??"",
style: Theme.of(context).textTheme.headline6?.copyWith(fontSize: 14, color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context),
),
],

@ -1,15 +1,16 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:signature/signature.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../loaders/image_loader.dart';
class ESignature extends StatefulWidget {
final String oldSignature;
final Uint8List newSignature;
final Function(Uint8List) onSaved;
const ESignature({Key key, this.oldSignature, this.onSaved, this.newSignature}) : super(key: key);
final String? oldSignature;
final Uint8List? newSignature;
final Function(Uint8List)? onSaved;
const ESignature({Key? key, this.oldSignature, this.onSaved, this.newSignature}) : super(key: key);
@override
State<ESignature> createState() => _ESignatureState();
@ -23,7 +24,7 @@ class _ESignatureState extends State<ESignature> {
exportBackgroundColor: Colors.white,
);
Uint8List signature;
Uint8List? signature;
bool _unpaint = false;
@override
@ -51,14 +52,14 @@ class _ESignatureState extends State<ESignature> {
padding: const EdgeInsets.only(bottom: 8),
height: 90 * AppStyle.getScaleFactor(context),
child: signature != null ?
Image.memory(signature):
Image.memory(signature!):
ImageLoader(
boxFit: BoxFit.contain,
url: widget.oldSignature)
url: widget.oldSignature??"")
),
FormField<String>(
onSaved: (_) async {
widget.onSaved(signature);
widget.onSaved!(signature!);
},
builder: (FormFieldState<String> state) {
return Column(

@ -1,18 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/device/device.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class AutoCompleteDeviceField extends StatefulWidget {
final Device initialValue;
final String hospitalId;
final Function(String) onPick;
final String? hospitalId;
final Function(String)? onPick;
const AutoCompleteDeviceField({Key key, this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
const AutoCompleteDeviceField({Key? key, required this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
@override
_AutoCompleteDeviceFieldState createState() => _AutoCompleteDeviceFieldState();
@ -20,10 +23,10 @@ class AutoCompleteDeviceField extends StatefulWidget {
class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
SettingProvider _settingProvider;
DevicesProvider _devicesProvider;
UserProvider _userProvider;
TextEditingController _controller;
SettingProvider? _settingProvider;
DevicesProvider? _devicesProvider;
UserProvider? _userProvider;
TextEditingController? _controller;
@override
void initState() {
@ -33,7 +36,7 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
@override
void dispose() {
_controller.dispose();
_controller?.dispose();
super.dispose();
}
@override
@ -70,22 +73,22 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
textInputAction: TextInputAction.search,
),
suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
return await _devicesProvider!.getDevicesList(
host: _settingProvider?.host??"",
user: _userProvider?.user??User(),
hospitalId: widget.hospitalId??"",
serialNumber: value,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.serialNumber),
subtitle: Text(device.model+"/"+device.brand),
title: Text(device.serialNumber??""),
subtitle: Text("${device.model??""}/${device.brand??""}"),
);
},
onSuggestionSelected: (device) {
_controller.text = device.serialNumber;
widget.onPick(device.id);
_controller?.text = device.serialNumber??"";
widget.onPick!(device.id??"");
},
),
);

@ -1,20 +1,21 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/equipment/single_device_picker.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/device/device.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import 'single_device_picker.dart';
class DeviceButton extends StatelessWidget {
final Function(Device) onDevicePick;
final Function(Device)? onDevicePick;
final Device device;
const DeviceButton({Key key, this.device, this.onDevicePick}) : super(key: key);
const DeviceButton({Key? key, required this.device, this.onDevicePick}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
@ -32,7 +33,7 @@ class DeviceButton extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text(
_subtitle.pickDevice,
_subtitle?.pickDevice??"",
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
@ -44,24 +45,24 @@ class DeviceButton extends StatelessWidget {
child: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
"${_subtitle.sn} : " + device.serialNumber,
"${_subtitle?.sn??""} : ${device.serialNumber??""}",
style: Theme.of(context).textTheme.subtitle1,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
color: Theme.of(context).textTheme.subtitle1?.color,
),
Text(
"${_subtitle.brand} : " + device.brand,
"${_subtitle?.brand} : ${device.brand}",
style: Theme.of(context).textTheme.subtitle2,
),
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
color: Theme.of(context).textTheme.subtitle1?.color,
),
Text(
"${_subtitle.model} : " + device.model,
"${_subtitle?.model} : ${device.model}",
style: Theme.of(context).textTheme.subtitle2,
),
],
@ -72,7 +73,7 @@ class DeviceButton extends StatelessWidget {
),
onPressed: () async {
Device _device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Device;
onDevicePick(_device);
onDevicePick!(_device);
});
}
}

@ -1,17 +1,19 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/device/device.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class DeviceItem extends StatelessWidget {
final Device device;
final Function(Device) onPressed;
final Function(Device)? onPressed;
const DeviceItem({Key key, this.device, this.onPressed}) : super(key: key);
const DeviceItem({Key? key, required this.device, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 6),
child: ElevatedButton(
@ -25,11 +27,11 @@ class DeviceItem extends StatelessWidget {
),
onPressed: (){
onPressed(device);
onPressed!(device);
},
child: ListTile(
title: Text("${_subtitle.sn} : " + device.serialNumber,
style: Theme.of(context).textTheme.headline6.copyWith(
title: Text("${_subtitle?.sn} : ${device.serialNumber}",
style: Theme.of(context).textTheme.headline6?.copyWith(
color: AColors.white
),
@ -38,14 +40,14 @@ class DeviceItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(color: Theme.of(context).scaffoldBackgroundColor,),
Text("${_subtitle.brand} : " + device.brand,
style: Theme.of(context).textTheme.subtitle1.copyWith(
Text("${_subtitle?.brand} : ${device.brand}",
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white
),
),
Divider(color: Theme.of(context).scaffoldBackgroundColor,),
Text("${_subtitle.model} : " + device.model,
style: Theme.of(context).textTheme.subtitle1.copyWith(
Text("${_subtitle?.model} : ${device.model}",
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white
),
),

@ -1,18 +1,19 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/equipment/device_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import 'package:test_sa/views/widgets/qr/scan_qr.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/device/device.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../app_text_form_field.dart';
import '../loaders/loading_manager.dart';
import '../loaders/no_item_found.dart';
import '../qr/scan_qr.dart';
import 'device_item.dart';
class SingleDevicePicker extends StatefulWidget {
static final String id = "/single-device-Picker";
final bool sandraChoice = true;
@ -21,12 +22,12 @@ class SingleDevicePicker extends StatefulWidget {
}
class _SingleDevicePickerState extends State<SingleDevicePicker> {
DevicesProvider _devicesProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
DevicesProvider? _devicesProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
List<Device> _searchableList = [];
bool _firstTime = true;
Subtitle _subtitle;
Subtitle? _subtitle;
_getDevice(String result) async {
if(result == null) return;
@ -37,15 +38,15 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
return const Center(child: CircularProgressIndicator());
}
);
List<Device> devices = await _devicesProvider.getDevicesListBySN(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: _userProvider.user.hospital.id,
List<Device> devices = await _devicesProvider!.getDevicesListBySN(
host: _settingProvider?.host??"",
user: _userProvider?.user??User(),
hospitalId: _userProvider?.user?.hospital?.id??"",
sn: result
);
Navigator.of(context).pop();
if(devices.isEmpty){
Fluttertoast.showToast(msg: _subtitle.noDeviceFound);
Fluttertoast.showToast(msg: _subtitle?.noDeviceFound??"");
return;
}
Navigator.of(context).pop(devices.first);
@ -67,23 +68,23 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
if(_firstTime && _devicesProvider.devices != null){
_searchableList.addAll(_devicesProvider.devices);
if(_firstTime && _devicesProvider?.devices != null){
_searchableList.addAll(_devicesProvider?.devices??[]);
_firstTime = false;
}
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
resizeToAvoidBottomInset: false,
body: LoadingManager(
isLoading: _devicesProvider.isLoading,
stateCode: _devicesProvider.stateCode,
isFailedLoading: _devicesProvider.devices == null,
isLoading: _devicesProvider?.isLoading??false,
stateCode: _devicesProvider?.stateCode??0,
isFailedLoading: _devicesProvider?.devices == null,
onRefresh: () async {
_devicesProvider.reset();
await _devicesProvider.getEquipment(
user: _userProvider.user,
host: _settingProvider.host,
hospitalId: _userProvider.user.hospital.id
_devicesProvider?.reset();
await _devicesProvider?.getEquipment(
user: _userProvider?.user??User(),
host: _settingProvider?.host??"",
hospitalId: _userProvider?.user?.hospital?.id??""
);
},
child: Column(
@ -94,13 +95,13 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
child: Column(
children: [
ATextFormField(
hintText: _subtitle.searchBySn,
hintText: _subtitle?.searchBySn??"",
style: Theme.of(context).textTheme.subtitle1,
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_devicesProvider.devices.where(
(element) => element.serialNumber.toLowerCase().contains(
_searchableList.addAll(_devicesProvider!.devices!.where(
(element) => element.serialNumber!.toLowerCase().contains(
value.toLowerCase()
)
).toList());
@ -114,8 +115,8 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
suffixIcon: const Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_devicesProvider.devices.where(
(element) => element.number.toLowerCase().contains(
_searchableList.addAll(_devicesProvider!.devices!.where(
(element) => element.number!.toLowerCase().contains(
value.toLowerCase()
)
).toList());
@ -127,7 +128,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
),
Expanded(
child: _searchableList.isEmpty ?
NoItemFound(message: _subtitle.noDeviceFound,):
NoItemFound(message: _subtitle?.noDeviceFound??"",):
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
@ -150,7 +151,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
child: const Icon(Icons.qr_code_scanner),
onPressed: () async {
String result = await Navigator.of(context).push(
MaterialPageRoute(builder: (_)=> const ScanQr()),
MaterialPageRoute(builder: (_)=> ScanQr()),
) as String;
_getDevice(result);
},

@ -1,12 +1,14 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/views/app_style/colors.dart';
import '../../../models/gas_refill/gas_refill_details.dart';
import '../../app_style/colors.dart';
class GasRefillCreateDetailsItem extends StatelessWidget {
final GasRefillDetails model;
final VoidCallback onDelete;
final VoidCallback? onDelete;
const GasRefillCreateDetailsItem({Key key, this.model, this.onDelete}) : super(key: key);
const GasRefillCreateDetailsItem({Key? key, required this.model, this.onDelete}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -15,7 +17,7 @@ class GasRefillCreateDetailsItem extends StatelessWidget {
children: [
Row(
children: [
Expanded(child: Text(model.type.label)),
Expanded(child: Text(model.type?.label??"")),
IconButton(
onPressed: onDelete,
color: AColors.red,
@ -25,14 +27,14 @@ class GasRefillCreateDetailsItem extends StatelessWidget {
),
Row(
children: [
Text(model.requestedQuantity.toStringAsFixed(0)),
Text(model.requestedQuantity?.toStringAsFixed(0)??""),
],
),
if(model.deliveredQuantity != null)
Row(
children: [
const Text("Delivered Quantity"),
Text(model.deliveredQuantity.toStringAsFixed(0)),
Text(model.deliveredQuantity?.toStringAsFixed(0)??""),
],
),
const Divider(),

@ -1,30 +1,26 @@
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/models/user.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/user/requests/report/create_service_report.dart';
import 'package:test_sa/views/pages/user/requests/report/future_service_report.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../models/gas_refill/gas_refill_model.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../requests/request_status.dart';
class GasRefillItem extends StatelessWidget {
final int index;
final GasRefillModel item;
final Function(GasRefillModel) onPressed;
const GasRefillItem({Key key, this.item, this.onPressed, this.index}) : super(key: key);
final Function(GasRefillModel)? onPressed;
const GasRefillItem({Key? key, required this.item, this.onPressed, required this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
User _user = Provider.of<UserProvider>(context,listen: false).user;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
User? _user = Provider.of<UserProvider>(context,listen: false).user;
Color itemColor = index % 2 == 0
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onPrimary;
@ -46,7 +42,7 @@ class GasRefillItem extends StatelessWidget {
),
//padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8),
onPressed: (){
onPressed(item);
onPressed!(item);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -59,7 +55,7 @@ class GasRefillItem extends StatelessWidget {
children: [
Text(
item.title ?? "-----",
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
color: onItemColor,
fontSize: 16,
fontWeight: FontWeight.bold
@ -69,15 +65,15 @@ class GasRefillItem extends StatelessWidget {
children: [
Expanded(
child: Text(
_subtitle.hospital,
style: Theme.of(context).textTheme.subtitle2.copyWith(
_subtitle?.hospital??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
),
Text(
item.clientName,
style: Theme.of(context).textTheme.subtitle2.copyWith(
item.clientName??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
@ -89,14 +85,14 @@ class GasRefillItem extends StatelessWidget {
children: [
Expanded(
child: Text(
_subtitle.status,
style: Theme.of(context).textTheme.subtitle2.copyWith(
_subtitle?.status??"",
style: Theme.of(context).textTheme.subtitle2?.copyWith(
color: onItemColor,
),
),
),
StatusLabel(label: item.status.label,
color: AColors.getGasStatusColor(item.status.id)
StatusLabel(label: item.status?.label??"",
color: AColors.getGasStatusColor(item.status?.id??0)
),
],
),

@ -1,28 +1,31 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/gas_refill/gas_refill_model.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/pages/user/gas_refill/gas_refill_details.dart';
import 'package:test_sa/views/widgets/gas_refill/gas_refill_item.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/gas_refill/gas_refill_model.dart';
import '../../../models/subtitle.dart';
import '../../pages/user/gas_refill/gas_refill_details.dart';
import '../loaders/lazy_loading.dart';
import '../loaders/no_item_found.dart';
import 'gas_refill_item.dart';
class GasRefillList extends StatelessWidget {
final List<GasRefillModel> items;
final bool nextPage;
final Future<void> Function() onLazyLoad;
const GasRefillList({Key key, this.items, this.nextPage, this.onLazyLoad}) : super(key: key);
const GasRefillList({Key? key, required this.items, required this.nextPage, required this.onLazyLoad}) : super(key: key);
@override
Widget build(BuildContext context) {
if(items.length == 0){
Subtitle subtitle = AppLocalization.of(context).subtitle;
return NoItemFound(message: subtitle.noServiceRequestFound,);
Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
return NoItemFound(message: subtitle?.noServiceRequestFound??"",);
}
return LazyLoading(
nextPage: nextPage,
onLazyLoad: onLazyLoad,
onLoadingEnd: () {},
child: ListView.builder(
//physics: const BouncingScrollPhysics(),
itemCount: items.length,

@ -1,42 +1,44 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import 'package:test_sa/views/widgets/titles/app_title.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/validator/validator.dart';
import '../../../models/gas_refill/gas_refill_details.dart';
import '../../../models/subtitle.dart';
import '../app_text_form_field.dart';
import '../requests/info_row.dart';
import '../titles/app_sub_title.dart';
import '../titles/app_title.dart';
class GasRefillUpdateDetailsItem extends StatelessWidget {
final GasRefillDetails details;
final bool enableEdit;
final bool validate;
final bool? enableEdit;
final bool? validate;
const GasRefillUpdateDetailsItem({Key key, this.details, this.enableEdit, this.validate}) : super(key: key);
const GasRefillUpdateDetailsItem({Key? key, required this.details, this.enableEdit, this.validate}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle subtitle = AppLocalization.of(context).subtitle;
Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ATitle(details.type.label),
ATitle(details.type?.label??""),
RequestInfoRow(
title: "Cylinder Size",
info: details.cylinderSize.label,
info: details.cylinderSize?.label??"",
),
RequestInfoRow(
title: "Requested Quantity",
info: details.requestedQuantity.toStringAsFixed(0),
info: details.requestedQuantity?.toStringAsFixed(0)??"",
),
enableEdit ?
(enableEdit??false) ?
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(subtitle.quantity),
if(validate && details.deliveredQuantity == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
ASubTitle(subtitle?.quantity??""),
if((validate??false) && details.deliveredQuantity == null)
ASubTitle(subtitle?.requiredWord??"",color: Colors.red,),
SizedBox(height: 4,),
ATextFormField(
initialValue: (details.deliveredQuantity ?? "").toString(),
@ -54,7 +56,7 @@ class GasRefillUpdateDetailsItem extends StatelessWidget {
):
RequestInfoRow(
title: "Delivered Quantity",
info: details.deliveredQuantity.toStringAsFixed(0),
info: details.deliveredQuantity?.toStringAsFixed(0)??"",
),
//SizedBox(height: 16,)
],

@ -1,29 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/hospitals_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_item.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/hospitals_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/hospital.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import 'hospital_item.dart';
class HospitalAutoCompleteField extends StatefulWidget {
final String initialValue;
final Function(String) onSearch;
final Function(String) onSave;
final String? initialValue;
final Function(String)? onSearch;
final Function(String)? onSave;
const HospitalAutoCompleteField({Key key, this.onSearch, this.initialValue, this.onSave}) : super(key: key);
const HospitalAutoCompleteField({Key? key, this.onSearch, this.initialValue, this.onSave}) : super(key: key);
@override
_HospitalAutoCompleteFieldState createState() => _HospitalAutoCompleteFieldState();
}
class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
SettingProvider _settingProvider;
TextEditingController _controller;
SettingProvider? _settingProvider;
late TextEditingController _controller;
@override
void initState() {
@ -40,7 +42,7 @@ class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
@override
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Container(
padding: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
@ -60,7 +62,7 @@ class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
controller: _controller,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: _subtitle.hospital,
hintText: _subtitle?.hospital,
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
@ -68,10 +70,10 @@ class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
),
textInputAction: TextInputAction.search,
onEditingComplete: () {
widget.onSearch(_controller.text);
widget.onSearch!(_controller.text);
}),
suggestionsCallback: (vale) async {
return await HospitalsProvider().getHospitalsList(host: _settingProvider.host, title: vale);
return await HospitalsProvider().getHospitalsList(host: _settingProvider?.host??"", title: vale, user: User());
},
itemBuilder: (context, hospital) {
return HospitalItem(
@ -79,7 +81,7 @@ class _HospitalAutoCompleteFieldState extends State<HospitalAutoCompleteField> {
);
},
onSuggestionSelected: (hospital) {
widget.onSearch(hospital.name);
widget.onSearch!(hospital.name??"");
},
),
);

@ -1,20 +1,21 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/hospitals/single_hospital_picker.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/hospital.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import 'single_hospital_picker.dart';
class HospitalButton extends StatelessWidget {
final Function(Hospital) onHospitalPick;
final Function(Hospital)? onHospitalPick;
final Hospital hospital;
const HospitalButton({Key key, this.hospital, this.onHospitalPick}) : super(key: key);
const HospitalButton({Key? key, required this.hospital, this.onHospitalPick}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
@ -29,8 +30,8 @@ class HospitalButton extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
hospital?.name ?? _subtitle.pickHospital,
style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 14, color: AColors.grey3A),
hospital.name ?? _subtitle?.pickHospital??"",
style: Theme.of(context).textTheme.bodyText1?.copyWith(fontSize: 14, color: AColors.grey3A),
// textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
textAlign: TextAlign.left,
@ -42,7 +43,7 @@ class HospitalButton extends StatelessWidget {
),
onPressed: () async {
Hospital _hospital = await Navigator.of(context).pushNamed(SingleHospitalPicker.id) as Hospital;
onHospitalPick(_hospital);
onHospitalPick!(_hospital);
});
}
}

@ -1,12 +1,14 @@
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
import '../../../models/hospital.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class HospitalItem extends StatelessWidget {
final Hospital hospital;
final Function(Hospital) onPressed;
final Function(Hospital)? onPressed;
const HospitalItem({Key key, this.hospital, this.onPressed}) : super(key: key);
const HospitalItem({Key? key, required this.hospital, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
@ -22,12 +24,12 @@ class HospitalItem extends StatelessWidget {
),
onPressed: onPressed == null ? null : (){
onPressed(hospital);
onPressed!(hospital);
},
child: ListTile(
title: Text(
hospital.name ?? "",
style: Theme.of(context).textTheme.subtitle1.copyWith(
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white
),
textDirection: TextDirection.rtl,

@ -1,15 +1,16 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/hospitals_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_item.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/hospitals_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/hospital.dart';
import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../app_text_form_field.dart';
import '../loaders/loading_manager.dart';
import '../loaders/no_item_found.dart';
import 'hospital_item.dart';
class SingleHospitalPicker extends StatefulWidget {
static final String id = "/single-Hospital-Picker";
final bool sandraChoice = true;
@ -18,28 +19,28 @@ class SingleHospitalPicker extends StatefulWidget {
}
class _SingleHospitalPickerState extends State<SingleHospitalPicker> {
HospitalsProvider _hospitalsProvider;
SettingProvider _settingProvider;
HospitalsProvider? _hospitalsProvider;
SettingProvider? _settingProvider;
List<Hospital> _searchableList = [];
bool _firstTime = true;
@override
Widget build(BuildContext context) {
_hospitalsProvider = Provider.of<HospitalsProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
if(_firstTime && _hospitalsProvider.hospitals != null){
_searchableList.addAll(_hospitalsProvider.hospitals);
if(_firstTime && _hospitalsProvider?.hospitals != null){
_searchableList.addAll(_hospitalsProvider?.hospitals??[]);
_firstTime = false;
}
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold(
resizeToAvoidBottomInset: false,
body: LoadingManager(
isLoading: _hospitalsProvider.isLoading,
stateCode: _hospitalsProvider.stateCode,
isFailedLoading: _hospitalsProvider.hospitals == null,
isLoading: _hospitalsProvider?.isLoading??false,
stateCode: _hospitalsProvider?.stateCode??0,
isFailedLoading: _hospitalsProvider?.hospitals == null,
onRefresh: () async {
_hospitalsProvider.reset();
await _hospitalsProvider.getHospitals(host: _settingProvider.host,);
_hospitalsProvider?.reset();
await _hospitalsProvider?.getHospitals(host: _settingProvider?.host??"", user: User(), title: '');
},
child: Column(
children: [
@ -47,13 +48,13 @@ class _SingleHospitalPickerState extends State<SingleHospitalPicker> {
Padding(
padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16),
child: ATextFormField(
hintText: _subtitle.searchByName,
hintText: _subtitle?.searchByName??"",
style: Theme.of(context).textTheme.headline6,
suffixIcon: Icon(Icons.search_rounded),
onChange: (value){
_searchableList.clear();
_searchableList.addAll(_hospitalsProvider.hospitals.where(
(element) => element.name.toLowerCase().contains(
_searchableList.addAll(_hospitalsProvider!.hospitals!.where(
(element) => element.name!.toLowerCase().contains(
value.toLowerCase()
)
).toList());
@ -63,7 +64,7 @@ class _SingleHospitalPickerState extends State<SingleHospitalPicker> {
),
Expanded(
child: _searchableList.isEmpty ?
NoItemFound(message: _subtitle.noHospitalFound,):
NoItemFound(message: _subtitle?.noHospitalFound??"",):
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,

@ -1,16 +1,18 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../loaders/image_loader.dart';
class ImageItem extends StatelessWidget {
final String url;
final bool isVideo;
final VoidCallback onPressed;
final VoidCallback? onPressed;
const ImageItem({
Key key,
this.url,
Key? key,
required this.url,
this.isVideo = false,
this.onPressed
}) : super(key: key);

@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/sizing.dart';
import 'image_item.dart';
import 'images_viewer.dart';
class ImagesList extends StatelessWidget {
final List<String> images;
final EdgeInsets padding;
final EdgeInsets? padding;
const ImagesList({Key key, this.images, this.padding}) : super(key: key);
const ImagesList({Key? key, required this.images, this.padding}) : super(key: key);
@override
Widget build(BuildContext context) {

@ -1,13 +1,14 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import '../../app_style/sizing.dart';
import '../loaders/image_loader.dart';
class ImagesViewer extends StatelessWidget {
final List<String> images;
final int initialIndex;
const ImagesViewer({
Key key,
this.images,
Key? key,
required this.images,
this.initialIndex = 0,
}) : super(key: key);

@ -3,24 +3,25 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart';
import '../../app_style/sizing.dart';
class AMiniOneImagePicker extends StatefulWidget {
final Function(File) onPick;
final File image;
final String label;
final bool error;
const AMiniOneImagePicker({Key key, this.label, this.error,this.image, this.onPick}) : super(key: key);
final Function(File)? onPick;
final File? image;
final String? label;
final bool? error;
const AMiniOneImagePicker({Key? key, this.label, this.error,this.image, this.onPick}) : super(key: key);
@override
_AMiniOneImagePickerState createState() => _AMiniOneImagePickerState();
}
class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
File _image;
Subtitle _subtitle;
late File? _image;
late Subtitle _subtitle;
@override
void initState() {
super.initState();
@ -28,7 +29,7 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)!.subtitle!;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -52,7 +53,7 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
SizedBox(height: 4,),
Text(
_subtitle.requiredImage,
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
color: Colors.red
),
textScaleFactor: AppStyle.getScaleFactor(context),
@ -78,12 +79,12 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
_image == null ? _subtitle.pickImage : _image.path.split("/").last,
_image == null ? _subtitle.pickImage : _image!.path.split("/").last,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
onPressed: () async {
ImageSource source = await showDialog(
ImageSource? source = await showDialog(
context: context,
builder: (_) => CupertinoAlertDialog(
actions: <Widget>[
@ -102,8 +103,9 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
],
)
);
if(source == null)
if(source == null) {
return;
}
final pickedFile = await ImagePicker().pickImage(
source: source,
@ -116,7 +118,7 @@ class _AMiniOneImagePickerState extends State<AMiniOneImagePicker> {
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
widget.onPick(_image);
widget.onPick!(_image!);
} else {
}

@ -4,33 +4,33 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_flat_button.dart';
import '../../../controllers/localization/localization.dart';
import '../../../extensions/int_extensions.dart';
import '../../../models/subtitle.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../buttons/app_flat_button.dart';
import 'multi_image_picker_item.dart';
class MultiImagesPicker extends StatefulWidget {
final String label;
final bool error;
final List<File> images;
final String? label;
final bool? error;
final List<File>? images;
const MultiImagesPicker({Key key, this.images, this.label, this.error = false}) : super(key: key);
const MultiImagesPicker({Key? key, this.images, this.label, this.error = false}) : super(key: key);
@override
_MultiImagesPickerState createState() => _MultiImagesPickerState();
}
class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProviderStateMixin {
Size _size;
late Size _size;
@override
Widget build(BuildContext context) {
_size = MediaQuery.of(context).size;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
Subtitle _subtitle = AppLocalization.of(context)!.subtitle!;
return Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
@ -49,7 +49,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
Expanded(
child: Text(
widget.label ?? _subtitle.images,
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
fontSize: 14,
),
textScaleFactor: AppStyle.getScaleFactor(context),
@ -66,14 +66,14 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
12.height,
AnimatedSize(
duration: Duration(milliseconds: 400),
child: !widget.error
child: !(widget.error??false)
? SizedBox.shrink()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_subtitle.imagesRequired,
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
fontSize: 14,
color: AColors.red,
),
@ -88,7 +88,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
child: Container(
key: ValueKey(widget.images.length),
key: ValueKey(widget.images?.length),
width: _size.width,
height: 200 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(
@ -99,7 +99,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
border: Border.all(color: Theme.of(context).primaryColor, width: 2),
borderRadius: BorderRadius.circular(8 * AppStyle.getScaleFactor(context)),
),
child: widget.images.isEmpty
child: (widget.images?.isEmpty??false)
? MaterialButton(
onPressed: () {
onImagePick(_subtitle);
@ -117,12 +117,12 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
scrollDirection: Axis.horizontal,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(widget.images.length, (index) {
File _image = widget.images[index];
children: List.generate(widget.images!.length, (index) {
File _image = widget.images![index];
return MultiImagesPickerItem(
image: _image,
onRemoveTap: (image) {
widget.images.remove(image);
widget.images?.remove(image);
setState(() {});
},
);
@ -136,7 +136,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
}
onImagePick(Subtitle _subtitle) async {
if (widget.images.length >= 5) {
if (widget.images!.length >= 5) {
Fluttertoast.showToast(msg: _subtitle.maxImagesNumberIs5);
return;
}
@ -165,7 +165,7 @@ class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProvid
if (pickedFile != null) {
File _fileImage = File(pickedFile.path);
if (_fileImage != null) {
widget.images.insert(0, _fileImage);
widget.images?.insert(0, _fileImage);
setState(() {});
}
}

@ -1,17 +1,18 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../buttons/app_back_button.dart';
class MultiImagesPickerItem extends StatelessWidget {
final File image;
final Function(File) onRemoveTap;
final Function(File)? onRemoveTap;
const MultiImagesPickerItem({Key key, this.image, this.onRemoveTap}) : super(key: key);
const MultiImagesPickerItem({Key? key, required this.image, this.onRemoveTap}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -66,7 +67,7 @@ class MultiImagesPickerItem extends StatelessWidget {
child: Icon(Icons.remove_circle,color: AColors.red,)
),
onPressed: (){
onRemoveTap(image);
onRemoveTap!(image);
},
)
),

@ -3,24 +3,25 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart';
import '../../app_style/sizing.dart';
class AOneImagePicker extends StatefulWidget {
final Function(File) onPick;
final Function(File)? onPick;
final File image;
final String label;
final bool error;
const AOneImagePicker({Key key, this.label, this.error,this.image, this.onPick}) : super(key: key);
final String? label;
final bool? error;
const AOneImagePicker({Key? key, this.label, this.error,required this.image, this.onPick}) : super(key: key);
@override
_AOneImagePickerState createState() => _AOneImagePickerState();
}
class _AOneImagePickerState extends State<AOneImagePicker> {
File _image;
Subtitle _subtitle;
late File _image;
Subtitle? _subtitle;
@override
void initState() {
super.initState();
@ -28,7 +29,7 @@ class _AOneImagePickerState extends State<AOneImagePicker> {
}
@override
Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle;
_subtitle = AppLocalization.of(context)?.subtitle;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -51,8 +52,8 @@ class _AOneImagePickerState extends State<AOneImagePicker> {
children: [
SizedBox(height: 4,),
Text(
_subtitle.requiredImage,
style: Theme.of(context).textTheme.headline6.copyWith(
_subtitle?.requiredImage??"",
style: Theme.of(context).textTheme.headline6?.copyWith(
color: Colors.red
),
textScaleFactor: AppStyle.getScaleFactor(context),
@ -77,7 +78,7 @@ class _AOneImagePickerState extends State<AOneImagePicker> {
child: _image == null ?
Text(
_subtitle.pickImage,
_subtitle?.pickImage??"",
style: Theme.of(context).textTheme.headline6,
textScaleFactor: AppStyle.getScaleFactor(context),
):
@ -126,7 +127,7 @@ class _AOneImagePickerState extends State<AOneImagePicker> {
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
widget.onPick(_image);
widget.onPick!(_image);
}
});
},

@ -1,13 +1,15 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class ReportIssueItem extends StatelessWidget {
final bool isSelected;
final String issueInfo;
final Function(String,bool) onChange;
final bool? isSelected;
final String? issueInfo;
final Function(String,bool)? onChange;
const ReportIssueItem({
Key key,
Key? key,
this.isSelected,
this.issueInfo,
this.onChange
@ -19,7 +21,7 @@ class ReportIssueItem extends StatelessWidget {
splashColor: AColors.secondaryColor.withOpacity(.5),
padding: EdgeInsets.symmetric(vertical: 4),
onPressed: (){
onChange(issueInfo,!isSelected);
onChange!(issueInfo!,!isSelected!);
},
child: Column(
children: [
@ -43,7 +45,7 @@ class ReportIssueItem extends StatelessWidget {
child: Checkbox(
value: isSelected,
onChanged: (value){
onChange(issueInfo,value);
onChange!(issueInfo!,value!);
},
),
),

@ -1,13 +1,15 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class LandPageItem extends StatelessWidget {
final String text;
final IconData icon;
final VoidCallback onPressed;
final String? text;
final IconData? icon;
final VoidCallback? onPressed;
const LandPageItem({Key key, this.text, this.icon, this.onPressed}) : super(key: key);
const LandPageItem({Key? key, this.text, this.icon, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -35,7 +37,7 @@ class LandPageItem extends StatelessWidget {
color: AColors.primaryColor,
size: 42 * AppStyle.getScaleFactor(context),
),
Text(text, style: TextStyle(color: AColors.grey3A)),
Text(text??"", style: TextStyle(color: AColors.grey3A)),
],
),
),

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/sizing.dart';
import 'app_loading.dart';
class ALazyLoading extends StatelessWidget {
@override

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
class ALoading extends StatelessWidget {
const ALoading({Key key}) : super(key: key);
const ALoading({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

@ -1,12 +1,14 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/sizing.dart';
class FailedLoading extends StatelessWidget {
final String message;
final VoidCallback onReload;
final String? message;
final VoidCallback? onReload;
const FailedLoading({
Key key,
Key? key,
this.message,
this.onReload
}) : super(key: key);

@ -1,12 +1,12 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
class ImageLoader extends StatelessWidget {
final String url;
final BoxFit boxFit;
final Color color;
final Alignment alignment;
final String? url;
final BoxFit? boxFit;
final Color? color;
final Alignment? alignment;
const ImageLoader({
Key key,
Key? key,
this.url,
this.boxFit,
this.color,

@ -1,22 +1,22 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/subtitle.dart';
import '../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart';
import 'app_loading.dart';
import 'failed_loading.dart';
class LoadingManager extends StatefulWidget {
final bool isLoading;
final bool isFailedLoading;
final bool isNotPage;
final int progress;
final bool askOnBack;
final int stateCode;
final Future<void> Function() onRefresh;
final Widget child;
final bool? isLoading;
final bool? isFailedLoading;
final bool? isNotPage;
final int? progress;
final bool? askOnBack;
final int? stateCode;
final Future<void> Function()? onRefresh;
final Widget? child;
LoadingManager({
Key key,
Key? key,
this.isLoading,
this.isFailedLoading,
this.stateCode,
@ -37,7 +37,7 @@ class _LoadingManagerState extends State<LoadingManager> {
void initState() {
if(widget.onRefresh != null && widget.stateCode == null){
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
widget.onRefresh();
widget.onRefresh!();
});
}
super.initState();
@ -45,12 +45,12 @@ class _LoadingManagerState extends State<LoadingManager> {
@override
Widget build(BuildContext context) {
Subtitle subtitle = AppLocalization.of(context).subtitle;
Widget placeHolder;
Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
Widget? placeHolder;
// to load data if load not start
if(widget.isLoading == false && widget.stateCode == null){
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
widget.onRefresh();
widget.onRefresh!();
});
}
@ -58,7 +58,7 @@ class _LoadingManagerState extends State<LoadingManager> {
// return loading widget
if(widget.isLoading != false || widget.stateCode == null){
placeHolder = ALoading();
}else if(widget.isFailedLoading && !widget.isNotPage){
}else if((widget.isFailedLoading??false) && !(widget.isNotPage??false)){
// if failed return failed widget
placeHolder = FailedLoading(
message: HttpStatusManger.getStatusMessage(
@ -70,7 +70,7 @@ class _LoadingManagerState extends State<LoadingManager> {
// if load end successfully return loaded widget
return RefreshIndicator(
onRefresh: () async{
await widget.onRefresh();
await widget.onRefresh!();
},
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 400),

@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../app_style/sizing.dart';
class NoItemFound extends StatelessWidget {
final String message;
final String? message;
const NoItemFound({
Key key,
Key? key,
this.message,
}) : super(key: key);

@ -1,12 +1,14 @@
import 'package:test_sa/models/app_notification.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../../models/app_notification.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
class NotificationItem extends StatelessWidget {
final AppNotification notification;
final Function(AppNotification) onPressed;
const NotificationItem({Key key, this.notification, this.onPressed}) : super(key: key);
final Function(AppNotification)? onPressed;
const NotificationItem({Key? key, required this.notification, this.onPressed}) : super(key: key);
@override
@ -25,7 +27,7 @@ class NotificationItem extends StatelessWidget {
),
onPressed: (){
onPressed(notification);
onPressed!(notification);
},
child:Column(
@ -36,7 +38,7 @@ class NotificationItem extends StatelessWidget {
Expanded(
child: Text(
notification.title ?? "No Hospital Found",
style: Theme.of(context).textTheme.headline6.copyWith(
style: Theme.of(context).textTheme.headline6?.copyWith(
color: AColors.white,
fontSize: 16,
fontWeight: FontWeight.bold
@ -45,7 +47,7 @@ class NotificationItem extends StatelessWidget {
),
Text(
notification.date ?? "complaint not available",
style: Theme.of(context).textTheme.subtitle1.copyWith(
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white,
fontSize: 12,
fontWeight: FontWeight.bold
@ -56,7 +58,7 @@ class NotificationItem extends StatelessWidget {
Divider(color: AColors.white,),
Text(
notification.description ?? "complaint not available",
style: Theme.of(context).textTheme.subtitle1.copyWith(
style: Theme.of(context).textTheme.subtitle1?.copyWith(
color: AColors.white,
fontSize: 14,
),

@ -1,19 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../controllers/providers/api/parts_provider.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../models/part.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart';
import '../../app_style/sizing.dart';
import '../loaders/loading_manager.dart';
class AutoCompletePartsField extends StatefulWidget {
final String initialValue;
final Function(Part) onPick;
final bool clearAfterPick;
final String? initialValue;
final Function(Part)? onPick;
final bool? clearAfterPick;
const AutoCompletePartsField({Key key, this.initialValue, this.onPick, this.clearAfterPick = true}) : super(key: key);
const AutoCompletePartsField({Key? key, this.initialValue, this.onPick, this.clearAfterPick = true}) : super(key: key);
@override
_AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState();
@ -21,10 +24,10 @@ class AutoCompletePartsField extends StatefulWidget {
class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
SettingProvider _settingProvider;
PartsProvider _partsProvider;
UserProvider _userProvider;
TextEditingController _controller;
late SettingProvider _settingProvider;
late PartsProvider _partsProvider;
late UserProvider _userProvider;
late TextEditingController _controller;
@override
void initState() {
@ -50,8 +53,9 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
onRefresh: () async {
_partsProvider.reset();
await _partsProvider.getParts(
host: _settingProvider.host,
user: _userProvider.user,
host: _settingProvider.host??"",
user: _userProvider.user??User(),
title: '',
);
},
child: Container(
@ -83,23 +87,24 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
),
suggestionsCallback: (vale) async {
return await _partsProvider.getPartsList(
host: _settingProvider.host,
title: vale
host: _settingProvider.host??"",
title: vale,
user: User()
);
},
itemBuilder: (context, part) {
return ListTile(
title: Text(part.code),
subtitle: Text(part.name, style: Theme.of(context).textTheme.caption,),
title: Text(part.code??""),
subtitle: Text(part.name??"", style: Theme.of(context).textTheme.caption,),
);
},
onSuggestionSelected: (part) {
if(widget.clearAfterPick){
if(widget.clearAfterPick??false){
_controller.clear();
} else{
_controller.text = part.code;
_controller.text = part.code??"";
}
widget.onPick(part);
widget.onPick!(part);
},
),
),

@ -1,13 +1,14 @@
import 'package:test_sa/models/part.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
import 'package:flutter/material.dart';
import '../../../models/part.dart';
import '../../app_style/sizing.dart';
import '../buttons/app_icon_button2.dart';
class PartItem extends StatefulWidget {
final Part part;
final Function(Part) onDelete;
final Part? part;
final Function(Part)? onDelete;
const PartItem({Key key, this.part, this.onDelete}) : super(key: key);
const PartItem({Key? key, this.part, this.onDelete}) : super(key: key);
@override
_PartItemState createState() => _PartItemState();
@ -29,8 +30,8 @@ class _PartItemState extends State<PartItem> {
Row(
children: [
Expanded(
child: Text(widget.part.code,
style: Theme.of(context).textTheme.bodyText1.copyWith(
child: Text(widget.part?.code??"",
style: Theme.of(context).textTheme.bodyText1?.copyWith(
fontSize: 12,
fontWeight: FontWeight.bold
),
@ -40,21 +41,21 @@ class _PartItemState extends State<PartItem> {
iconData: Icons.add,
color: Theme.of(context).primaryColor,
onPressed: (){
widget.part.quantity++;
widget.part?.quantity++;
setState(() {});
},
),
AIconButton2(
iconData: Icons.remove,
color: Theme.of(context).primaryColor,
onPressed: widget.part.quantity < 2 ? null : (){
widget.part.quantity--;
onPressed: widget.part!.quantity < 2 ? null : (){
widget.part?.quantity--;
setState(() {});
},
),
SizedBox(width: 8*AppStyle.getScaleFactor(context),),
Text(widget.part.quantity.toString(),
style: Theme.of(context).textTheme.headline6.copyWith(
Text(widget.part?.quantity.toString()??"",
style: Theme.of(context).textTheme.headline6?.copyWith(
//fontSize: 12,
//fontWeight: FontWeight.bold
),
@ -62,9 +63,9 @@ class _PartItemState extends State<PartItem> {
SizedBox(width: 8*AppStyle.getScaleFactor(context),),
],
),
widget.part.name == null ? SizedBox.shrink() :
Text(widget.part.name,
style: Theme.of(context).textTheme.caption.copyWith(
widget.part?.name == null ? SizedBox.shrink() :
Text(widget.part?.name??"",
style: Theme.of(context).textTheme.caption?.copyWith(
fontSize: 11,
fontWeight: FontWeight.bold
),
@ -77,7 +78,7 @@ class _PartItemState extends State<PartItem> {
iconData: Icons.close,
color: Colors.red,
onPressed: (){
widget.onDelete(widget.part);
widget.onDelete!(widget.part!);
},
),

@ -1,19 +1,24 @@
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../../controllers/providers/api/devices_provider.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../models/device/device.dart';
import '../../../../models/lookup.dart';
import '../../../../models/user.dart';
import '../../../app_style/colors.dart';
import '../../../app_style/sizing.dart';
class AutoCompleteDeviceNumberField extends StatefulWidget {
final Lookup initialValue;
final String hospitalId;
final Function(Lookup) onPick;
final Lookup? initialValue;
final String? hospitalId;
final Function(Lookup)? onPick;
const AutoCompleteDeviceNumberField({Key?
const AutoCompleteDeviceNumberField({Key key, this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
key, this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
@override
State<AutoCompleteDeviceNumberField> createState() => _AutoCompleteDeviceNumberFieldState();
@ -21,10 +26,10 @@ class AutoCompleteDeviceNumberField extends StatefulWidget {
class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumberField> {
SettingProvider _settingProvider;
DevicesProvider _devicesProvider;
UserProvider _userProvider;
TextEditingController _controller;
late SettingProvider _settingProvider;
late DevicesProvider _devicesProvider;
late UserProvider _userProvider;
late TextEditingController _controller;
@override
void initState() {
@ -72,21 +77,21 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
),
suggestionsCallback: (vale) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
host: _settingProvider.host??"",
user: _userProvider.user??User(),
hospitalId: widget.hospitalId??"",
number: vale,
);
},
itemBuilder: (context, device) {
return ListTile(
title: Text(device.number),
title: Text(device.number??""),
subtitle: Text("${device.model}/${device.brand}"),
);
},
onSuggestionSelected: (device) {
_controller.text = device.number;
widget.onPick(Lookup(id: int.tryParse(device.id),label: device.number));
_controller.text = device.number??"";
widget.onPick!(Lookup(id: int.tryParse(device.id!),label: device.number));
},
),
);

@ -1,19 +1,21 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../models/pantry/calibration_tools.dart';
import '../../app_style/sizing.dart';
import '../buttons/app_button.dart';
import '../buttons/app_small_button.dart';
import '../date_and_time/date_picker.dart';
import '../titles/app_sub_title.dart';
import 'auto_complete_fields/auto_complete_devices_field.dart';
class PentryCalibrationToolForm extends StatefulWidget {
final List<CalibrationTool> models;
final bool enableValidate;
final List<CalibrationTool>? models;
final bool? enableValidate;
const PentryCalibrationToolForm({
Key key, this.models, this.enableValidate,
Key? key, this.models, this.enableValidate,
}) : super(key: key);
@override
@ -25,7 +27,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final subtitle = AppLocalization.of(context)?.subtitle;
final userProvider = Provider.of<UserProvider>(context);
return ListView.builder(
padding: EdgeInsets.only(
@ -34,18 +36,18 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemCount: widget.models!.length + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
if(index == widget.models?.length){
return AButton(
text: subtitle.add,
text: subtitle?.add??"",
onPressed: (){
widget.models.add(CalibrationTool());
widget.models?.add(CalibrationTool());
setState(() {});
},
);
}
final model = widget.models[index];
final model = widget.models![index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
@ -57,9 +59,9 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
text: subtitle?.delete??"",
onPressed: (){
widget.models.remove(model);
widget.models?.remove(model);
setState(() {});
},
),
@ -70,7 +72,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
const SizedBox(height: 4,),
AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber,
hospitalId: userProvider.user.hospital.id,
hospitalId: userProvider.user?.hospital?.id,
onPick: (number){
model.assetsNumber = number;
},
@ -86,7 +88,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
Divider(color: Theme.of(context).textTheme.titleMedium?.color,),
],
);
}

@ -1,21 +1,23 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_status_mune.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_visit_status_mune.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/user_provider.dart';
import '../../../models/pantry/pentry.dart';
import '../../app_style/sizing.dart';
import '../app_text_form_field.dart';
import '../date_and_time/date_picker.dart';
import '../images/mini_one_image_picker.dart';
import '../status/pentry/pentry_status_mune.dart';
import '../status/pentry/pentry_visit_status_mune.dart';
import '../timer/app_timer.dart';
import '../titles/app_sub_title.dart';
class PentryInfoForm extends StatefulWidget {
final Pentry model;
final bool enableValidate;
final Pentry? model;
final bool? enableValidate;
const PentryInfoForm({
Key key, this.model, this.enableValidate,
Key? key, this.model, this.enableValidate,
}) : super(key: key);
@override
@ -26,7 +28,7 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final subtitle = AppLocalization.of(context)!.subtitle;
final userProvider = Provider.of<UserProvider>(context);
return ListView(
padding: EdgeInsets.only(
@ -40,24 +42,24 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
children: [
const SizedBox(height: 8,),
const ASubTitle("PPM Visit Status"),
if(widget.enableValidate && widget.model.ppmVisitStatus == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
if((widget.enableValidate??false) && widget.model?.ppmVisitStatus == null)
ASubTitle(subtitle?.requiredWord??"",color: Colors.red,),
const SizedBox(height: 4,),
PentryVisitsStatusMenu(
initialValue: widget.model.ppmVisitStatus,
initialValue: widget.model?.ppmVisitStatus,
onSelect: (status){
widget.model.ppmVisitStatus = status;
widget.model?.ppmVisitStatus = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Timer"),
if(widget.enableValidate && widget.model?.timer?.endAt == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
if((widget.enableValidate??false) && widget.model?.timer?.endAt == null)
ASubTitle(subtitle?.requiredWord??"",color: Colors.red,),
const SizedBox(height: 4,),
AppTimer(
timer: widget.model.timer,
timer: widget.model?.timer,
onChange: (timer) async{
widget.model.timer = timer;
widget.model?.timer = timer;
return true;
},
),
@ -67,22 +69,22 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
// ASubTitle(subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
PentryStatusMenu(
initialValue: widget.model.status,
initialValue: widget.model?.status,
onSelect: (status){
widget.model.status = status;
widget.model?.status = status;
},
),
const SizedBox(height: 8,),
const ASubTitle("Actual Visit Date"),
if(widget.enableValidate && widget.model.actualVisitDate == null)
ASubTitle(subtitle.requiredWord,color: Colors.red,),
if((widget.enableValidate ?? false ) && widget.model?.actualVisitDate == null)
ASubTitle(subtitle?.requiredWord??"",color: Colors.red,),
const SizedBox(height: 4,),
ADatePicker(
date: widget.model.actualVisitDate,
date: widget.model?.actualVisitDate,
from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date){
if(date == null) return;
widget.model.actualVisitDate = date;
widget.model?.actualVisitDate = date;
setState(() {});
},
),
@ -90,21 +92,21 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
const ASubTitle("Traveling Hours"),
const SizedBox(height: 4,),
ATextFormField(
initialValue: (widget.model.travelingHours ?? "").toString(),
initialValue: (widget.model?.travelingHours ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1,
textInputType: TextInputType.number,
onChange: (value){
widget.model.travelingHours = value;
widget.model?.travelingHours = value;
},
),
const SizedBox(height: 12,),
const ASubTitle("PPM Attachment"),
AMiniOneImagePicker(
//error: _validate && _serviceReport.image == null,
image: widget.model.imageFile,
image: widget.model?.imageFile,
onPick: (image){
widget.model.imageFile =image;
widget.model?.imageFile =image;
},
),
const SizedBox(height: 8,),

@ -1,18 +1,20 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/pm_kit.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/lookup.dart';
import '../../../models/pantry/pm_kit.dart';
import '../../app_style/sizing.dart';
import '../app_text_form_field.dart';
import '../buttons/app_button.dart';
import '../buttons/app_small_button.dart';
import '../parts/auto_complete_parts_field.dart';
import '../titles/app_sub_title.dart';
class PentryPMKitForm extends StatefulWidget {
final List<PMKit> models;
final bool enableValidate;
final List<PMKit>? models;
final bool? enableValidate;
const PentryPMKitForm({
Key key, this.models, this.enableValidate,
Key? key, this.models, this.enableValidate,
}) : super(key: key);
@override
@ -23,7 +25,7 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final subtitle = AppLocalization.of(context)?.subtitle;
return ListView.builder(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
@ -31,18 +33,18 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemCount: (widget.models?.length??0) + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
if(index == widget.models?.length){
return AButton(
text: subtitle.add,
text: subtitle?.add??"",
onPressed: (){
widget.models.add(PMKit());
widget.models?.add(PMKit());
setState(() {});
},
);
}
final model = widget.models[index];
final model = widget.models![index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
@ -54,9 +56,9 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
text: subtitle?.delete??"",
onPressed: (){
widget.models.remove(model);
widget.models?.remove(model);
setState(() {});
},
),
@ -69,7 +71,7 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
clearAfterPick: false,
initialValue: (model.itemCode?.label ?? "").toString(),
onPick: (part){
model.itemCode = Lookup(id: int.tryParse(part.id),label: part.code);
model.itemCode = Lookup(id: int.tryParse(part.id!),label: part.code);
},
),
const SizedBox(height: 8,),
@ -145,7 +147,7 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
Divider(color: Theme.of(context).textTheme.titleMedium?.color,),
],
);
}

@ -1,17 +1,19 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_task_status_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../controllers/localization/localization.dart';
import '../../../models/pantry/ppm_check_list.dart';
import '../../app_style/sizing.dart';
import '../app_text_form_field.dart';
import '../buttons/app_button.dart';
import '../buttons/app_small_button.dart';
import '../status/pentry/pentry_task_status_mune.dart';
import '../titles/app_sub_title.dart';
class PentryPPMCheckListForm extends StatefulWidget {
final List<PPMCheckList> models;
final bool enableValidate;
final List<PPMCheckList>? models;
final bool? enableValidate;
const PentryPPMCheckListForm({
Key key, this.models, this.enableValidate,
Key? key, this.models, this.enableValidate,
}) : super(key: key);
@override
@ -23,7 +25,7 @@ class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
@override
Widget build(BuildContext context) {
final subtitle = AppLocalization.of(context).subtitle;
final subtitle = AppLocalization.of(context)?.subtitle;
return ListView.builder(
padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context),
@ -31,18 +33,18 @@ class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
right: 12 * AppStyle.getScaleFactor(context),
bottom: 80 * AppStyle.getScaleFactor(context)
),
itemCount: widget.models.length + 1,
itemCount: (widget.models?.length??0) + 1,
itemBuilder: (context,index){
if(index == widget.models.length){
if(index == widget.models?.length){
return AButton(
text: subtitle.add,
text: subtitle?.add??"",
onPressed: (){
widget.models.add(PPMCheckList());
widget.models!.add(PPMCheckList());
setState(() {});
},
);
}
final model = widget.models[index];
final model = widget.models![index];
return ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
@ -54,9 +56,9 @@ class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
if(index != 0)
ASmallButton(
color: Theme.of(context).colorScheme.error,
text: subtitle.delete,
text: subtitle!.delete,
onPressed: (){
widget.models.remove(model);
widget.models!.remove(model);
setState(() {});
},
),
@ -75,7 +77,7 @@ class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
},
),
const SizedBox(height: 8,),
ASubTitle(subtitle.status),
ASubTitle(subtitle?.status??""),
const SizedBox(height: 4,),
PentryTaskStatusMenu(
initialValue: model.status,
@ -108,7 +110,7 @@ class _PentryPPMCheckListFormState extends State<PentryPPMCheckListForm> {
},
),
const SizedBox(height: 8,),
Divider(color: Theme.of(context).textTheme.titleMedium.color,),
Divider(color: Theme.of(context).textTheme.titleMedium?.color,),
],
);
}

Loading…
Cancel
Save