Changes for Phase-1

merge-requests/1/merge
Sikander Saleem 3 years ago
parent c713184c78
commit 9ce90c745f

@ -96,7 +96,7 @@
"nameExist": "Name Exist",
"newServiceRequest": "New Service Request",
"newWord": "New",
"noDateFound": "No Date Found",
"noDateFound": "No Data Found",
"noDeviceFound": "No Device Found",
"noHospitalFound": "No Client Found",
"noModelFound": "No Model Found",

@ -0,0 +1,13 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
extension IntExtensions on int {
Widget get height => SizedBox(height: toDouble());
Widget get width => SizedBox(width: toDouble());
Widget get divider => Divider(height: toDouble(), thickness: toDouble(), color: AColors.greyEF);
Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble());
}

@ -0,0 +1,245 @@
//
// import 'package:flutter/cupertino.dart';
// import 'package:intl/intl.dart';
//
// extension CapExtension on String {
// String get toCamelCase => "${this[0].toUpperCase()}${this.substring(1)}";
//
// String get inCaps => '${this[0].toUpperCase()}${this.substring(1)}';
//
// String get allInCaps => this.toUpperCase();
//
// String get capitalizeFirstofEach => this.trim().length > 0 ? this.trim().toLowerCase().split(" ").map((str) => str.inCaps).join(" ") : "";
// }
//
// extension EmailValidator on String {
// Widget get toWidget => Text(this);
//
// Widget toText10({Color? color, bool isBold = false, int? maxlines, FontStyle? fontStyle}) => Text(
// this,
// maxLines: maxlines,
// style: TextStyle(fontSize: 10, fontStyle: fontStyle ?? FontStyle.normal, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
// );
//
// Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isBold = false, int maxLine = 0}) => Text(
// this,
// maxLines: (maxLine > 0) ? maxLine : null,
// style: TextStyle(
// fontSize: 11,
// fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
// color: color ?? MyColors.darkTextColor,
// letterSpacing: -0.33,
// decoration: isUnderLine ? TextDecoration.underline : null,
// ),
// );
//
// Widget toText12({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => Text(
// this,
// textAlign: isCenter ? TextAlign.center : null,
// maxLines: (maxLine > 0) ? maxLine : null,
// style: TextStyle(
// fontSize: 12,
// fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
// color: color ?? MyColors.darkTextColor,
// letterSpacing: -0.72,
// decoration: isUnderLine ? TextDecoration.underline : null,
// ),
// );
//
// Widget toText12Auto({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0}) => AutoSizeText(
// this,
// textAlign: isCenter ? TextAlign.center : null,
// maxLines: (maxLine > 0) ? maxLine : null,
// minFontSize: 8,
// style: TextStyle(
// fontSize: 12,
// fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
// color: color ?? MyColors.darkTextColor,
// letterSpacing: -0.72,
// decoration: isUnderLine ? TextDecoration.underline : null,
// ),
// );
//
// Widget toTextAuto({
// Color? color,
// bool isUnderLine = false,
// bool isBold = false,
// bool isCenter = false,
// int maxLine = 0,
// double fontSize = 12,
// double letterSpacing = -0.72,
// double height = 1,
// }) =>
// AutoSizeText(
// this,
// textAlign: isCenter ? TextAlign.center : null,
// maxLines: (maxLine > 0) ? maxLine : null,
// minFontSize: 5,
// style: TextStyle(
// fontSize: fontSize,
// fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
// color: color ?? MyColors.darkTextColor,
// letterSpacing: letterSpacing,
// decoration: isUnderLine ? TextDecoration.underline : null,
// ),
// );
//
// Widget toText13({Color? color, bool isUnderLine = false}) => Text(
// this,
// style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.52, decoration: isUnderLine ? TextDecoration.underline : null),
// );
//
// Widget toText14({Color? color, bool isUnderLine = false, bool isBold = false, FontWeight? weight, int? maxlines, TextAlign? textAlign, bool isCenter = false}) => Text(
// this,
// textAlign: isCenter ? TextAlign.center : (textAlign ?? TextAlign.left),
// maxLines: maxlines,
// style: TextStyle(
// color: color ?? MyColors.darkTextColor,
// fontSize: 14,
// letterSpacing: -0.48,
// fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600),
// decoration: isUnderLine ? TextDecoration.underline : null),
// );
//
// Widget toText16({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines, double? height}) => Text(
// this,
// maxLines: maxlines,
// style: TextStyle(
// color: color ?? MyColors.darkTextColor,
// fontSize: 16,
// letterSpacing: -0.64,
// height: height,
// fontWeight: isBold ? FontWeight.bold : FontWeight.w600,
// decoration: isUnderLine ? TextDecoration.underline : null,
// ),
// );
//
// Widget toText17({Color? color, bool isBold = false}) => Text(
// this,
// style: TextStyle(color: color ?? MyColors.darkTextColor, fontSize: 17, letterSpacing: -0.68, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toText18({Color? color, bool isBold = false, bool isCentered = false}) => Text(
// this,
// textAlign: isCentered ? TextAlign.center : null,
// style: TextStyle(fontSize: 18, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.08),
// );
//
// Widget toText19({Color? color, bool isBold = false}) => Text(
// this,
// style: TextStyle(fontSize: 19, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -1.14),
// );
//
// Widget toText20({Color? color, bool isBold = false, bool isCentered = false}) => Text(
// this,
// textAlign: isCentered ? TextAlign.center : null,
// style: TextStyle(fontSize: 20, fontWeight: isBold ? FontWeight.bold : FontWeight.w600, color: color ?? MyColors.darkTextColor, letterSpacing: -0.4),
// );
//
// Widget toText21({Color? color, bool isBold = false, FontWeight? weight, int? maxlines}) => Text(
// this,
// maxLines: maxlines,
// style: TextStyle(color: color ?? MyColors.grey3AColor, fontSize: 21, letterSpacing: -0.84, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.w600)),
// );
//
// Widget toText22({Color? color, bool isBold = false, bool isCentered = false}) => Text(
// this,
// textAlign: isCentered ? TextAlign.center : null,
// style: TextStyle(height: 1, color: color ?? MyColors.darkTextColor, fontSize: 22, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toText24({Color? color, bool isBold = false}) => Text(
// this,
// style: TextStyle(height: 23 / 24, color: color ?? MyColors.darkTextColor, fontSize: 24, letterSpacing: -1.44, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toText30({Color? color, bool isBold = false}) => Text(
// this,
// style: TextStyle(height: 20 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.2, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toText32({Color? color, bool isBold = false, bool isCentered = false}) => Text(
// this,
// textAlign: isCentered ? TextAlign.center : null,
// style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 32, letterSpacing: -1.92, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toText44({Color? color, bool isBold = false}) => Text(
// this,
// style: TextStyle(height: 32 / 32, color: color ?? MyColors.darkTextColor, fontSize: 44, letterSpacing: -2.64, fontWeight: isBold ? FontWeight.bold : FontWeight.w600),
// );
//
// Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {
// String upper = "";
// String lower = "";
// String heading = this;
// if (heading.isNotEmpty) {
// List<String> data = heading.split(" ");
//
// if (data.length > 1) {
// upper = data[0];
// data.removeAt(0);
// lower = data.join(" ");
// } else {
// lower = data[0];
// }
// }
// if (upperHeading.isNotEmpty) {
// upper = upperHeading;
// }
// if (lowerHeading.isNotEmpty) {
// lower = lowerHeading;
// }
//
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// if (upper.isNotEmpty) upper.toText12(),
// lower.toText24(isBold: true),
// ],
// );
// }
//
// bool isValidEmail() {
// return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
// }
//
// String toFormattedDate() {
// String date = this.split("T")[0];
// String time = this.split("T")[1];
// var dates = date.split("-");
// return "${dates[2]} ${getMonth(int.parse(dates[1]))} ${dates[0]} ${DateFormat('hh:mm a').format(DateFormat('hh:mm:ss').parse(time))}";
// }
//
// String getMonth(int month) {
// switch (month) {
// case 1:
// return "January";
// case 2:
// return "February";
// case 3:
// return "March";
// case 4:
// return "April";
// case 5:
// return "May";
// case 6:
// return "June";
// case 7:
// return "July";
// case 8:
// return "August";
// case 9:
// return "September";
// case 10:
// return "October";
// case 11:
// return "November";
// case 12:
// return "December";
// default:
// return "";
// }
// }
// }

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:test_sa/views/app_style/colors.dart';
extension WidgetExtensions on Widget {
Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);
Widget get expanded => Expanded(child: this);
Widget get center => Center(child: this);
Widget circle(double _value) => ClipRRect(borderRadius: BorderRadius.circular(_value), child: this);
Widget paddingAll(double _value) => Padding(padding: EdgeInsets.all(_value), child: this);
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this);
Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this);
}

@ -92,7 +92,7 @@ class MyApp extends StatelessWidget {
title: 'ATOMS',
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: "Swiss",
fontFamily: "Poppins",
//canvasColor: AColors.primaryColor,
scaffoldBackgroundColor: AColors.scaffoldBackgroundColor,
primaryColor: AColors.primaryColor,

@ -4,6 +4,7 @@ class AColors {
AColors._();
static const Color white = Color(0xffffffff);
static const Color black = Color(0xff000000);
static const Color grey3A = Color(0xff2e303a);
static const Color grey = Color(0xffe1e7e7);
static const green = Colors.green;
static const Color orange = Colors.orange;
@ -12,9 +13,11 @@ class AColors {
static const Color deepRed = Color(0xFFD32F2F);
static const Color scaffoldBackgroundColor = Color(0xffffffff);
static const Color secondaryColor = Color(0xff111427);
static const Color primaryColor = Color(0xff3B7097);
static const Color primaryColor = Color(0xff5bb0da);
static const Color cyan = Color(0xff4A8DB7);
static const Color onPrimaryColor = Color(0xffffffff);
static Color inputFieldBackgroundColor = Color(0xfff5f5f5);
static Color greyEF = Color(0xffEFEFEF);
static Color getRequestStatusColor(int id){
switch(id){

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
class AppStyle {
AppStyle._();
static const double borderRadius = 12;
static const double borderRadius = 10;
static const BoxShadow boxShadow = BoxShadow(
color: Colors.black26,

@ -5,6 +5,7 @@ import 'package:test_sa/controllers/http_status_manger/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_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/extensions/int_extensions.dart';
import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/subtitle.dart';
@ -18,6 +19,7 @@ import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart';
class RequestDeviceTransfer extends StatefulWidget {
static const String id = "/request-device-transfer";
const RequestDeviceTransfer({Key key}) : super(key: key);
@ -39,20 +41,20 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void setState(VoidCallback fn){
if(mounted) super.setState(() {});
void setState(VoidCallback fn) {
if (mounted) super.setState(() {});
}
_onSubmit() async {
_validate = true;
if(!_formKey.currentState.validate()){
if (!_formKey.currentState.validate()) {
setState(() {});
return false;
}
_formKey.currentState.save();
if(!_formModel.validate()) {
setState(() { });
if (!_formModel.validate()) {
setState(() {});
return false;
}
@ -64,23 +66,18 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
host: _settingProvider.host,
model: _formModel,
);
_isLoading =false;
_isLoading = false;
setState(() {});
if(status >= 200 && status < 300){
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
);
Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
}
@ -95,7 +92,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
_subtitle = AppLocalization.of(context).subtitle;
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context,listen: false);
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
body: Form(
@ -116,11 +113,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
padding: const EdgeInsets.all(8.0),
child: Text(
"Transfer Device",
style: Theme.of(context).textTheme.headline5.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 28,
fontWeight: FontWeight.bold
),
style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold),
),
),
),
@ -138,14 +131,17 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// _formModel.title = value;
// },
// ),
const SizedBox(height: 8,),
12.height,
const ASubTitle("Device"),
if(_validate && _formModel.device == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
if (_validate && _formModel.device == null)
ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
),
6.height,
DeviceButton(
device: _formModel.device,
onDevicePick: (device){
onDevicePick: (device) {
_formModel.device = device;
setState(() {});
},
@ -162,39 +158,44 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
// setState(() {});
// },
// ),
const SizedBox(height: 8,),
12.height,
const ASubTitle("Destination Client"),
if(_validate && _formModel.receiver.client == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
if (_validate && _formModel.receiver.client == null)
ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
),
6.height,
HospitalButton(
hospital: _formModel.receiver.client,
onHospitalPick: (hospital){
onHospitalPick: (hospital) {
_formModel.receiver.client = hospital;
setState(() {});
},
),
const SizedBox(height: 8,),
12.height,
const ASubTitle("Destination Department"),
if(_validate && _formModel.receiver.department == null)
ASubTitle(_subtitle.requiredWord,color: Colors.red,),
const SizedBox(height: 4,),
if (_validate && _formModel.receiver.department == null)
ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
),
6.height,
DepartmentButton(
department: _formModel.receiver.department,
onDepartmentPick: (department){
onDepartmentPick: (department) {
_formModel.receiver.department = department;
setState(() {});
},
),
Padding(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
),
12.height,
AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
),
const SizedBox(height: 100,)
const SizedBox(
height: 100,
)
],
),
),
@ -204,4 +205,3 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
);
}
}

@ -1,7 +1,8 @@
import 'package:test_sa/controllers/api_routes/urls.dart';
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/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/controllers/validator/validator.dart';
@ -12,15 +13,13 @@ 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/buttons/app_flat_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import '../widgets/buttons/app_outlined_button.dart';
class Login extends StatefulWidget {
static final String id = "/login";
@override
_LoginState createState() => _LoginState();
}
@ -46,7 +45,7 @@ class _LoginState extends State<Login> {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Scaffold(
key: _scaffoldKey,
body:SafeArea(
body: SafeArea(
child: LoadingManager(
isLoading: _userProvider.isLoading || !_settingProvider.isLoaded,
isFailedLoading: false,
@ -59,97 +58,92 @@ class _LoginState extends State<Login> {
child: Column(
children: [
//AppNameBar(),
SizedBox(height: MediaQuery.of(context).size.height / 5,),
SizedBox(
height: MediaQuery.of(context).size.height / 7,
),
Hero(
tag: "logo",
child: Image(
height: _height/6,
height: _height / 6,
fit: BoxFit.contain,
image: AssetImage("assets/images/logo.png"),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 24 * AppStyle.getScaleFactor(context),
vertical: 24 * AppStyle.getScaleFactor(context)
),
padding: EdgeInsets.symmetric(horizontal: 24 * AppStyle.getScaleFactor(context), vertical: 24 * AppStyle.getScaleFactor(context)),
child: Column(
children: [
SizedBox(height: 24 * AppStyle.getScaleFactor(context),),
SizedBox(
height: 24 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _user?.userName,
hintText: _subtitle.name,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6,
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){
onSaved: (value) {
_user.userName = value;
},
),
SizedBox(height: 24 * AppStyle.getScaleFactor(context),),
SizedBox(height: 12),
ATextFormField(
initialValue: _user?.password,
hintText: _subtitle.password,
obscureText: _obscurePassword,
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.bodyText1,
prefixIconData: Icons.vpn_key_sharp,
textAlign: TextAlign.center,
validator: (value) => Validator.isValidPassword(value)
? null : _subtitle.passwordValidateMessage,
showPassword: (){
textAlign: TextAlign.left,
validator: (value) => Validator.isValidPassword(value) ? null : _subtitle.passwordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
},
onSaved: (value){
onSaved: (value) {
_user.password = value;
},
),
SizedBox(height: 32 * AppStyle.getScaleFactor(context),),
SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
),
AButton(
text: _subtitle.signIn,
onPressed: () async {
if(!_formKey.currentState.validate())
return;
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
int status = await _userProvider.login(
user: _user,
host: _settingProvider.host,
);
if(status >= 200 && status < 300){
if (status >= 200 && status < 300) {
_settingProvider.setUser(_userProvider.user);
if(_userProvider.user.isActive)
if (_userProvider.user.isActive)
Navigator.of(context).pushNamed(LandPage.id);
else
Fluttertoast.showToast(msg: _subtitle.activationAlert);
}else{
String errorMessage = status == 400
? _subtitle.wrongEmailOrPassword
: HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
} else {
String errorMessage = status == 400 ? _subtitle.wrongEmailOrPassword : HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
},
),
SizedBox(height: 140 * AppStyle.getScaleFactor(context),),
SizedBox(
height: 140 * AppStyle.getScaleFactor(context),
),
AOutLinedButton(
text: _subtitle.signUp,
//color: AColors.cyan,
onPressed: (){
onPressed: () {
Navigator.of(context).pushNamed(Register.id);
},
),
SizedBox(height: 32,),
SizedBox(
height: 32,
),
],
),
),

@ -1,3 +1,7 @@
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';
@ -5,21 +9,16 @@ 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/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/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 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
class Register extends StatefulWidget {
static final String id = "/register";
@override
_RegisterState createState() => _RegisterState();
}
@ -33,6 +32,7 @@ class _RegisterState extends State<Register> {
bool _obscurePassword = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
@ -42,7 +42,7 @@ class _RegisterState extends State<Register> {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Scaffold(
key: _scaffoldKey,
body:LoadingManager(
body: LoadingManager(
isLoading: _userProvider.isLoading,
isFailedLoading: false,
stateCode: 200,
@ -53,6 +53,7 @@ class _RegisterState extends State<Register> {
Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(20),
children: [
//AppNameBar(),
//SizedBox(height: 16,),
@ -61,190 +62,143 @@ class _RegisterState extends State<Register> {
child: Padding(
padding: const EdgeInsets.all(16),
child: Image(
height: _height/6,
height: _height / 6,
image: AssetImage("assets/images/logo.png"),
),
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 16),
margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: AColors.cyan,
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
boxShadow: [
BoxShadow(
color: AColors.grey,
offset: Offset(0,-1),
)
]
),
child: Column(
children: [
ATextFormField(
initialValue: _user.userName,
hintText: _subtitle.name,
prefixIconData: Icons.account_circle,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.hasValue(value)
? null : _subtitle.nameValidateMessage,
onSaved: (value){
_user.userName = value;
},
),
SizedBox(height: 8,),
ATextFormField(
initialValue: _user.email,
hintText: _subtitle.email,
prefixIconData: Icons.email,
textInputType: TextInputType.emailAddress,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.isEmail(value)
? null : _subtitle.emailValidateMessage,
onSaved: (value){
_user.email = value;
},
),
SizedBox(height: 8,),
ATextFormField(
initialValue: _user.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,
showPassword: (){
_obscurePassword = !_obscurePassword;
setState(() {});
},
onSaved: (value){
_user.password = value;
},
onChange: (value){
_user.password = value;
},
),
SizedBox(height: 8,),
ATextFormField(
initialValue: _user.password,
prefixIconData: Icons.vpn_key_sharp,
hintText: _subtitle.confirmPassword,
style: Theme.of(context).textTheme.headline6,
obscureText: _obscurePassword,
validator: (value) =>
_user.password == value
? null : _subtitle.confirmPasswordValidateMessage,
showPassword: (){
_obscurePassword = !_obscurePassword;
setState(() {});
},
),
SizedBox(height: 8,),
HospitalButton(
hospital: _user.hospital,
onHospitalPick: (hospital){
_user.hospital = hospital;
setState(() {});
},
),
SizedBox(height: 8,),
DepartmentButton(
department: _user.department,
onDepartmentPick: (department){
_user.department = department;
setState(() {});
},
),
SizedBox(height: 8,),
ATextFormField(
initialValue: _user.phoneNumber,
hintText: _subtitle.phoneNumber,
style: Theme.of(context).textTheme.headline6,
prefixIconData: Icons.phone_android,
validator: (value) =>
Validator.isPhoneNumber(value)
? null : _subtitle.phoneNumberValidateMessage,
textInputType: TextInputType.phone,
onSaved: (value){
_user.phoneNumber = value;
},
),
SizedBox(height: 8,),
ATextFormField(
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,
textInputType: TextInputType.phone,
onSaved: (value){
_user.whatsApp = value;
},
),
],
),
ATextFormField(
initialValue: _user.userName,
hintText: _subtitle.name,
prefixIconData: Icons.account_circle,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage,
onSaved: (value) {
_user.userName = value;
},
),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.email,
hintText: _subtitle.email,
prefixIconData: Icons.email,
textInputType: TextInputType.emailAddress,
style: Theme.of(context).textTheme.headline6,
validator: (value) => Validator.isEmail(value) ? null : _subtitle.emailValidateMessage,
onSaved: (value) {
_user.email = value;
},
),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.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,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
},
onSaved: (value) {
_user.password = value;
},
onChange: (value) {
_user.password = value;
},
),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.password,
prefixIconData: Icons.vpn_key_sharp,
hintText: _subtitle.confirmPassword,
style: Theme.of(context).textTheme.headline6,
obscureText: _obscurePassword,
validator: (value) => _user.password == value ? null : _subtitle.confirmPasswordValidateMessage,
showPassword: () {
_obscurePassword = !_obscurePassword;
setState(() {});
},
),
const SizedBox(height: 12),
HospitalButton(
hospital: _user.hospital,
onHospitalPick: (hospital) {
_user.hospital = hospital;
setState(() {});
},
),
SizedBox(height: 16,),
Center(
child: SizedBox(
height: _width / 8,
width: _width/1.2,
child: AButton(
text: _subtitle.signUp,
onPressed: () async {
if(!_formKey.currentState.validate())
return;
_formKey.currentState.save();
if(_user.hospital == null){
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
_subtitle.hospitalRequired
),
)
);
return;
}
if(_user.department == null){
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
_subtitle.unitRequired
),
)
);
return;
}
int status = await _userProvider.register(
user: _user,
host: _settingProvider.host,
);
if(status >= 200 && status < 300){
Fluttertoast.showToast(msg: _subtitle.activationAlert);
Navigator.of(context).pop();
}else{
String errorMessage = status == 402
? _subtitle.nameExist
: status == 401
const SizedBox(height: 12),
DepartmentButton(
department: _user.department,
onDepartmentPick: (department) {
_user.department = department;
setState(() {});
},
),
const SizedBox(height: 12),
ATextFormField(
initialValue: _user.phoneNumber,
hintText: _subtitle.phoneNumber,
style: Theme.of(context).textTheme.headline6,
prefixIconData: Icons.phone_android,
validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage,
textInputType: TextInputType.phone,
onSaved: (value) {
_user.phoneNumber = value;
},
),
SizedBox(height: 8),
ATextFormField(
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,
textInputType: TextInputType.phone,
onSaved: (value) {
_user.whatsApp = value;
},
),
const SizedBox(height: 12),
AButton(
text: _subtitle.signUp,
onPressed: () async {
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
if (_user.hospital == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.hospitalRequired),
));
return;
}
if (_user.department == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_subtitle.unitRequired),
));
return;
}
int status = await _userProvider.register(
user: _user,
host: _settingProvider.host,
);
if (status >= 200 && status < 300) {
Fluttertoast.showToast(msg: _subtitle.activationAlert);
Navigator.of(context).pop();
} else {
String errorMessage = status == 402
? _subtitle.nameExist
: status == 401
? _subtitle.emailExist
: HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
}
},
),
),
: HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
},
),
SizedBox(height: 32,),
],
),
),

@ -209,13 +209,10 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
_currentDetails.requestedQuantity = int.tryParse(value);
},
),
const SizedBox(height: 8,),
Padding(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.add,
onPressed: _addNewModel,
),
const SizedBox(height: 16),
AButton(
text: _subtitle.add,
onPressed: _addNewModel,
),
if(_formModel.details.isNotEmpty)
const ASubTitle("Gas Requests"),
@ -235,12 +232,10 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
);
}
),
Padding(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
),
const SizedBox(height: 16),
AButton(
text: _subtitle.submit,
onPressed: _onSubmit,
),
const SizedBox(height: 100,)
],

@ -53,7 +53,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
Column(
children: [
Container(
color:AColors.primaryColor,
color:AColors.white,
padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4),
child: Column(
children: [
@ -65,7 +65,7 @@ class _TrackGasRefillPageState extends State<TrackGasRefillPage>
child: Text(
_subtitle.serviceRequests,
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
color: AColors.grey3A,
fontStyle: FontStyle.italic
),
),

@ -1,5 +1,12 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:package_info/package_info.dart';
import 'package:provider/provider.dart';
import 'package:share/share.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart';
import 'package:test_sa/controllers/providers/api/departments_provider.dart';
@ -9,6 +16,8 @@ import 'package:test_sa/controllers/providers/api/regular_visits_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/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart';
@ -19,25 +28,17 @@ import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart';
import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart';
import 'package:test_sa/views/pages/user/notifications/notifications_page.dart';
import 'package:test_sa/views/pages/user/requests/create_request.dart';
import 'package:test_sa/views/pages/user/visits/preventive_maintenance_visits_page.dart';
import 'package:test_sa/views/pages/user/visits/regular_visits_page.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/dialogs/dialog.dart';
import 'package:test_sa/views/widgets/drawer/drawer_item.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:package_info/package_info.dart';
import 'package:provider/provider.dart';
import 'package:share/share.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../widgets/land_page/land_page_item.dart';
import 'profile_page.dart';
import 'requests/requests_page.dart';
class LandPage extends StatefulWidget {
static const String id = "/land-page";
@ -64,10 +65,9 @@ class _LandPageState extends State<LandPage> {
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
try{
try {
FirebaseNotificationManger.initialized(context);
}catch(error){
}
} catch (error) {}
});
super.initState();
}
@ -85,12 +85,9 @@ class _LandPageState extends State<LandPage> {
_preventiveMaintenanceVisitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(firstTime){
if(path != null){
Navigator.of(context).pushNamed(
"/"+path.split("/").first,
arguments: path.split("/").last
);
if (firstTime) {
if (path != null) {
Navigator.of(context).pushNamed("/" + path.split("/").first, arguments: path.split("/").last);
}
firstTime = false;
}
@ -101,26 +98,25 @@ class _LandPageState extends State<LandPage> {
bool result = await showDialog(
context: context,
builder: (_) => AAlertDialog(
title: _subtitle.exit,
content: _subtitle.exitAlert,
)
);
if(result == true){
if(Platform.isAndroid){
title: _subtitle.exit,
content: _subtitle.exitAlert,
));
if (result == true) {
if (Platform.isAndroid) {
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
} else {
exit(0);
}
}
return false;
},
child: Scaffold(
key: _scaffoldKey,
key: _scaffoldKey, //backgroundColor: Color(0xffF8F8F8),
body: SafeArea(
child: Stack(
children: [
ListView(
padding: const EdgeInsets.all(16.0),
children: [
//AppNameBar(),
// SizedBox(
@ -141,102 +137,100 @@ class _LandPageState extends State<LandPage> {
// )
// ),
// ),
SizedBox(height: 48 * AppStyle.getScaleFactor(context),),
Hero(
tag: "logo",
child: Image(
height: _height/6,
image: const AssetImage("assets/images/logo.png"),
),
SizedBox(
height: 48 * AppStyle.getScaleFactor(context),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: GridView.count(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
childAspectRatio: 1.15,
children: [
if (_userProvider.user.type == UsersTypes.normal_user)
// Hero(
// tag: "logo",
// child: Image(
// height: _height / 6,
// image: const AssetImage("assets/images/logo.png"),
// ),
// ),
GridView.count(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
childAspectRatio: 1,
children: [
if (_userProvider.user.type == UsersTypes.normal_user)
LandPageItem(
text: _subtitle.newServiceRequest,
icon: FontAwesomeIcons.tools,
onPressed: (){
onPressed: () {
Navigator.of(context).pushNamed(CreateRequestPage.id);
},
),
LandPageItem(
text: _subtitle.trackServiceRequest,
icon: FontAwesomeIcons.tasks,
onPressed: (){
Navigator.of(context).pushNamed(ServiceRequestsPage.id);
},
),
//if (_userProvider.user.type == UsersTypes.engineer)
LandPageItem(
text: _subtitle.preventiveMaintenance,
icon: FontAwesomeIcons.personWalking,
onPressed: (){
Navigator.of(context).pushNamed(RegularVisitsPage.id);
},
),
//if (_userProvider.user.type == UsersTypes.engineer)
// LandPageItem(
// text: _subtitle.preventiveMaintenance,
// icon: FontAwesomeIcons.toolbox,
// onPressed: (){
// Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id);
// },
// ),
if (_userProvider.user.type != UsersTypes.engineer)
LandPageItem(
text: _subtitle.trackServiceRequest,
icon: FontAwesomeIcons.tasks,
onPressed: () {
Navigator.of(context).pushNamed(ServiceRequestsPage.id);
},
),
//if (_userProvider.user.type == UsersTypes.engineer)
LandPageItem(
text: _subtitle.preventiveMaintenance,
icon: FontAwesomeIcons.personWalking,
onPressed: () {
Navigator.of(context).pushNamed(RegularVisitsPage.id);
},
),
//if (_userProvider.user.type == UsersTypes.engineer)
// LandPageItem(
// text: _subtitle.preventiveMaintenance,
// icon: FontAwesomeIcons.toolbox,
// onPressed: (){
// Navigator.of(context).pushNamed(PreventiveMaintenanceVisitsPage.id);
// },
// ),
if (_userProvider.user.type != UsersTypes.engineer)
LandPageItem(
text: "Request Gas Refill",
icon: FontAwesomeIcons.truckFast,
onPressed: (){
onPressed: () {
Navigator.of(context).pushNamed(RequestGasRefill.id);
},
),
LandPageItem(
text: "Track Gas Refill",
icon: Icons.content_paste_search,
onPressed: (){
Navigator.of(context).pushNamed(TrackGasRefillPage.id);
},
),
LandPageItem(
text: "transfer Device",
icon: FontAwesomeIcons.rightLeft,
onPressed: (){
Navigator.of(context).pushNamed(RequestDeviceTransfer.id);
},
),
LandPageItem(
text: "Track Device Transfer",
icon: FontAwesomeIcons.peopleCarryBox,
onPressed: (){
Navigator.of(context).pushNamed(TrackDeviceTransferPage.id);
},
),
],
),
LandPageItem(
text: "Track Gas Refill",
icon: Icons.content_paste_search,
onPressed: () {
Navigator.of(context).pushNamed(TrackGasRefillPage.id);
},
),
LandPageItem(
text: "transfer Device",
icon: FontAwesomeIcons.rightLeft,
onPressed: () {
Navigator.of(context).pushNamed(RequestDeviceTransfer.id);
},
),
LandPageItem(
text: "Track Device Transfer",
icon: FontAwesomeIcons.peopleCarryBox,
onPressed: () {
Navigator.of(context).pushNamed(TrackDeviceTransferPage.id);
},
),
],
),
SizedBox(height: 100,)
],
),
Align(
alignment: Alignment.topLeft,
child: ABackButton(
icon: Icons.power_settings_new_rounded,
onPressed: () async {
bool result = await showDialog(
context: context,
builder: (_) => AAlertDialog(
title: _subtitle.signOut,
content: _subtitle.signOutAlert,
)
);
if(result){
title: _subtitle.signOut,
content: _subtitle.signOutAlert,
));
if (result) {
_devicesProvider.reset();
_departmentsProvider.reset();
_serviceRequestsProvider.reset();
@ -251,213 +245,152 @@ class _LandPageState extends State<LandPage> {
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: AIconButton(
iconData: Icons.menu,
color: AColors.primaryColor,
buttonSize: 42,
backgroundColor: AColors.white,
onPressed: (){
onPressed: () {
_scaffoldKey.currentState.openEndDrawer();
},
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: EdgeInsets.all(16),
color: AColors.primaryColor,
child: Row(
children: [
AIconButton(
iconData: Icons.mail,
onPressed: (){
launch("mailto:customerservice@Test SA.com");
},
),
Expanded(
child: MaterialButton(
splashColor: AColors.secondaryColor.withOpacity(.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
8 * AppStyle.getScaleFactor(context)
),
color: AColors.onPrimaryColor
),
child: Icon(
Icons.phone_in_talk,
color: AColors.primaryColor ,
size: 32,
),
),
SizedBox(
width: 12 * AppStyle.getScaleFactor(context),
),
Text(
"${_subtitle.hotLine}\n15564",
style: Theme.of(context).textTheme.headline6.copyWith(
color: AColors.white,
letterSpacing: 2.75,
fontWeight: FontWeight.bold
),
),
],
),
onPressed: (){
launch("tel:15564");
},
),
),
AIconButton(
iconData: Icons.notifications,
onPressed: (){
Navigator.of(context).pushNamed(NotificationsPage.id);
},
),
],
),
),
),
],
),
),
endDrawer: Drawer(
child: Container(
color: AColors.primaryColor,
child: Column(
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: DrawerHeader(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onPrimary,
),
padding: EdgeInsets.zero,
child: MaterialButton(
padding: EdgeInsets.zero,
onPressed: (){
Navigator.of(context).pop();
Navigator.of(context).pushNamed(ProfilePage.id);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 100 * AppStyle.getScaleFactor(context),
width: 100 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).primaryColor,
width: 2
),
shape: BoxShape.circle
),
child: ClipOval(
child: ImageLoader(
url: "https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png",
),
),
),
Text(
_userProvider.user.userName,
style: Theme.of(context).textTheme.headline6.copyWith(
fontWeight: FontWeight.normal,
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
],
backgroundColor: Colors.white,
child: Column(
children: [
40.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const Icon(Icons.clear).onPress(() => Navigator.pop(context)),
],
).paddingOnly(left: 4, right: 14),
Row(
children: [
Container(
height: 50 * AppStyle.getScaleFactor(context),
width: 50 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(4),
decoration: BoxDecoration(border: Border.all(color: Theme.of(context).primaryColor, width: 2), shape: BoxShape.circle),
child: ClipOval(
child: ImageLoader(
url: "https://cdn.business2community.com/wp-content/uploads/2017/08/blank-profile-picture-973460_640.png",
),
),
),
),
Row(
children: [
Radio(
value: "en",
activeColor: Colors.white,
focusColor: Colors.white,
groupValue: _settingProvider.language,
onChanged: (value){
_settingProvider.setLanguage(value);
}
),
Text(
"English",
style: Theme.of(context).textTheme.bodyText1.copyWith(
color: Colors.white
12.width,
Text(
_userProvider.user.userName,
style: Theme.of(context).textTheme.headline6.copyWith(
fontWeight: FontWeight.w600,
),
textScaleFactor: AppStyle.getScaleFactor(context),
).expanded
],
).paddingOnly(left: 14, right: 14, top: 21, bottom: 21),
Divider(
height: 1,
thickness: 1,
color: AColors.greyEF,
),
ListView(
children: [
Row(
children: [
Radio(
value: "en",
activeColor: AColors.grey3A,
focusColor: AColors.grey3A,
groupValue: _settingProvider.language,
onChanged: (value) {
_settingProvider.setLanguage(value);
}),
Text(
"English",
style: Theme.of(context).textTheme.bodyText1.copyWith(color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context),
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
Radio(
value: "ar",
activeColor: Colors.white,
focusColor: Colors.white,
groupValue: _settingProvider.language,
onChanged: (value){
_settingProvider.setLanguage(value);
}
),
Text(
"عربي",
style: Theme.of(context).textTheme.bodyText1.copyWith(
color: Colors.white
Radio(
value: "ar",
activeColor: AColors.grey3A,
focusColor: AColors.grey3A,
groupValue: _settingProvider.language,
onChanged: (value) {
_settingProvider.setLanguage(value);
}),
Text(
"عربي",
style: Theme.of(context).textTheme.bodyText1.copyWith(color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context),
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
],
),
DrawerItem(
icon: FontAwesomeIcons.linkedinIn,
title: _subtitle.linkedIn,
onPressed: (){
launch("https://www.linkedin.com/company/Test SA/");
},
),
DrawerItem(
icon: FontAwesomeIcons.globe,
title: _subtitle.ourWebsite,
onPressed: (){
launch("https://www.Test SA.com/");
},
),
DrawerItem(
icon: Icons.share,
title: _subtitle.shareApp,
onPressed: () async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String shareLink =
"\n https://play.google.com/store/apps/details?id=" + packageInfo.packageName
+ "\n https://apps.apple.com/us/app/";
Share.share(shareLink);
},
),
Expanded(child: Center(child: Image.asset("assets/images/qr.jpeg"))),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
],
),
DrawerItem(
icon: Icons.notifications,
title: _subtitle.notifications,
onPressed: () {
Navigator.of(context).pushNamed(NotificationsPage.id);
},
),
DrawerItem(
icon: Icons.mail,
title: _subtitle.email,
onPressed: () {
launch("mailto:customerservice@Test SA.com");
},
),
DrawerItem(
icon: Icons.phone_in_talk,
title: "${_subtitle.hotLine} 15564",
onPressed: () {
launch("tel:15564");
},
),
DrawerItem(
icon: FontAwesomeIcons.linkedinIn,
title: _subtitle.linkedIn,
onPressed: () {
launch("https://www.linkedin.com/company/Test SA/");
},
),
DrawerItem(
icon: FontAwesomeIcons.globe,
title: _subtitle.ourWebsite,
onPressed: () {
launch("https://www.Test SA.com/");
},
),
DrawerItem(
icon: Icons.share,
title: _subtitle.shareApp,
onPressed: () async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String shareLink = "\n https://play.google.com/store/apps/details?id=" + packageInfo.packageName + "\n https://apps.apple.com/us/app/";
Share.share(shareLink);
},
),
],
).expanded,
Divider(height: 1, thickness: 1, color: AColors.greyEF),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Powered By NewTrack",
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontWeight: FontWeight.normal,
color: AColors.white
),
style: Theme.of(context).textTheme.headline6.copyWith(fontWeight: FontWeight.w500, color: AColors.grey3A, fontSize: 12),
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
],
),
6.width,
Image.asset("assets/images/qr.jpeg", width: 32, height: 32, color: AColors.grey3A)
],
).paddingOnly(left: 20, right: 20, top: 8, bottom: 8),
],
),
),
),

@ -11,11 +11,12 @@ 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/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/service_request/service_request.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';
@ -24,14 +25,15 @@ import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/sound/record_sound.dart';
import 'package:test_sa/views/widgets/speech_to_text/speech_to_text.dart';
class CreateRequestPage extends StatefulWidget {
static final String id = "/create-request";
@override
_CreateRequestPageState createState() => _CreateRequestPageState();
}
class _CreateRequestPageState extends State<CreateRequestPage> {
double _height;
UserProvider _userProvider;
SettingProvider _settingProvider;
@ -56,6 +58,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_height = MediaQuery.of(context).size.height;
@ -78,11 +81,13 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
ListView(
children: [
//AppNameBar(),
SizedBox(height: 16,),
SizedBox(
height: 16,
),
Hero(
tag: "logo",
child: Image(
height: _height/6,
height: _height / 6,
image: AssetImage("assets/images/logo.png"),
),
),
@ -91,104 +96,80 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
padding: const EdgeInsets.all(8.0),
child: Text(
_subtitle.newServiceRequest,
style: Theme.of(context).textTheme.headline5.copyWith(
color: AColors.cyan,
fontWeight: FontWeight.bold
),
style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600),
),
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 16),
margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: AColors.grey,
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
boxShadow: const [
BoxShadow(
color: AColors.grey,
offset: Offset(0,-1),
)
]
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8,),
_userProvider.user.hospital == null ? SizedBox.shrink() :
ATextFormField(
enable: false,
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospitalAlt,
prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6,
),
const SizedBox(height: 8,),
_userProvider.user.department == null ? SizedBox.shrink() :
ATextFormField(
enable: false,
initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound,
hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser,
prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6,
),
const SizedBox(height: 8,),
DeviceButton(
device: _device,
onDevicePick: (device){
_device = device;
setState(() {});
},
),
MultiImagesPicker(
label: _subtitle.deviceImages,
images: _deviceImages,
),
const SizedBox(height: 8,),
SpeechToTextButton(
controller: _controller,
),
const SizedBox(height: 8,),
ATextFormField(
controller: _controller,
initialValue: _serviceRequest.maintenanceIssue,
hintText: _subtitle.maintenanceIssue,
prefixIconData: FontAwesomeIcons.exclamationTriangle,
prefixIconSize: 36,
style: Theme.of(context).textTheme.headline6,
textInputType: TextInputType.multiline,
validator: (value) => Validator.hasValue(value)
? null : _subtitle.maintenanceIssueRequired,
onSaved: (value){
_serviceRequest.maintenanceIssue = value;
},
),
const SizedBox(height: 8,),
RecordSound(
onRecord: (audio){
_serviceRequest.audio = audio;
}
),
const SizedBox(height: 8,),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
_userProvider.user.hospital == null
? SizedBox.shrink()
: ATextFormField(
enable: false,
initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound,
hintText: _subtitle.hospital,
prefixIconData: FontAwesomeIcons.hospital,
style: Theme.of(context).textTheme.headline6,
),
12.height,
_userProvider.user.department == null
? SizedBox.shrink()
: ATextFormField(
enable: false,
initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound,
hintText: _subtitle.unite,
prefixIconData: FontAwesomeIcons.hospitalUser,
style: Theme.of(context).textTheme.headline6,
),
12.height,
DeviceButton(
device: _device,
onDevicePick: (device) {
_device = device;
setState(() {});
},
),
12.height,
MultiImagesPicker(
label: _subtitle.deviceImages,
images: _deviceImages,
),
12.height,
SpeechToTextButton(controller: _controller),
12.height,
ATextFormField(
controller: _controller,
initialValue: _serviceRequest.maintenanceIssue,
hintText: _subtitle.maintenanceIssue,
prefixIconData: FontAwesomeIcons.triangleExclamation,
style: Theme.of(context).textTheme.headline6,
textInputType: TextInputType.multiline,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.maintenanceIssueRequired,
onSaved: (value) {
_serviceRequest.maintenanceIssue = value;
},
),
12.height,
RecordSound(onRecord: (audio) {
_serviceRequest.audio = audio;
}),
12.height,
],
).paddingOnly(left: 20, right: 20),
Padding(
padding: const EdgeInsets.all(16.0),
padding: const EdgeInsets.all(20.0),
child: AButton(
text: _subtitle.submit,
onPressed: () async {
if(!_formKey.currentState.validate())
return;
if (!_formKey.currentState.validate()) return;
_formKey.currentState.save();
_serviceRequest.deviceId = _device?.id ?? "";
_isLoading =true;
_isLoading = true;
setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map(
(e) => base64Encode(e.readAsBytesSync())).toList();
if(_serviceRequest.audio != null){
_serviceRequest.devicePhotos = _deviceImages.map((e) => base64Encode(e.readAsBytesSync())).toList();
if (_serviceRequest.audio != null) {
final file = File(_serviceRequest.audio);
_serviceRequest.audio = base64Encode(file.readAsBytesSync());
}
@ -198,23 +179,18 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
host: _settingProvider.host,
serviceRequest: _serviceRequest,
);
_isLoading =false;
_isLoading = false;
setState(() {});
if(status >= 200 && status < 300){
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
msg: _subtitle.requestCompleteSuccessfully,
);
Navigator.of(context).pop();
}else{
String errorMessage = HttpStatusManger.getStatusMessage(
status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
errorMessage
),
)
);
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
}
},
),

@ -1,6 +1,6 @@
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/sizing.dart';
class ATextFormField extends StatefulWidget {
final Function(String) onSaved;
final Function(String) validator;
@ -22,57 +22,51 @@ class ATextFormField extends StatefulWidget {
final TextInputAction textInputAction;
final VoidCallback onAction;
const ATextFormField({
Key key,
this.onSaved,
this.validator,
this.node,
this.onChange,
this.obscureText,
this.showPassword,
this.hintText,
this.labelText,
this.textInputType = TextInputType.text,
this.initialValue,
this.enable = true,
this.style,
this.textAlign,
this.suffixIcon,
this.prefixIconData,
this.prefixIconSize,
this.controller,
this.textInputAction,
this.onAction
}) : super(key: key);
const ATextFormField(
{Key key,
this.onSaved,
this.validator,
this.node,
this.onChange,
this.obscureText,
this.showPassword,
this.hintText,
this.labelText,
this.textInputType = TextInputType.text,
this.initialValue,
this.enable = true,
this.style,
this.textAlign,
this.suffixIcon,
this.prefixIconData,
this.prefixIconSize,
this.controller,
this.textInputAction,
this.onAction})
: super(key: key);
@override
State<ATextFormField> createState() => _ATextFormFieldState();
}
class _ATextFormFieldState extends State<ATextFormField> {
@override
void initState() {
if(widget.controller != null)
widget.controller.text = widget.initialValue;
if (widget.controller != null) widget.controller.text = widget.initialValue;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: 16
),
height: widget.textInputType == TextInputType.multiline ? null : 50,
padding: EdgeInsets.only(left: 12, right: 12),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color:AColors.black),
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
color: Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
),
boxShadow: [
AppStyle.boxShadow
]
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: TextFormField(
focusNode: widget.node,
@ -81,33 +75,32 @@ class _ATextFormFieldState extends State<ATextFormField> {
initialValue: widget.controller != null ? null : widget.initialValue,
validator: widget.validator,
onChanged: widget.onChange,
textAlign: widget.textAlign ?? TextAlign.center,
textAlign: TextAlign.left,
obscureText: widget.obscureText ?? false,
keyboardType: widget.textInputType,
maxLines: widget.textInputType == TextInputType.multiline ? null : 1,
obscuringCharacter: "",
controller: widget.controller,
textInputAction:
widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next,
textInputAction: widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next,
onEditingComplete: widget.onAction ?? () => FocusScope.of(context).nextFocus(),
style: widget.style,
// style: widget.style,
style: Theme.of(context).textTheme.bodyText1,
decoration: InputDecoration(
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
hintText: widget.hintText,
labelText: widget.labelText,
suffixIcon: widget.suffixIcon,
prefixIcon: widget.prefixIconData == null ? null : Icon(
widget.prefixIconData,
size: widget.prefixIconSize == null
? 32 * AppStyle.getScaleFactor(context)
: (widget.prefixIconSize - 10) * AppStyle.getScaleFactor(context),
color: AColors.black,
)
),
border: InputBorder.none,
suffixIconConstraints: BoxConstraints(minWidth: 0),
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
constraints: BoxConstraints(),
errorStyle: TextStyle(height: 0.3),
//contentPadding: EdgeInsets.only(left: 0),
hintText: widget.hintText,
labelText: widget.labelText,
//suffixIcon: widget.suffixIcon,
suffixIcon: widget.prefixIconData == null
? null
: Icon(widget.prefixIconData,
size: widget.prefixIconSize == null ? 20 * AppStyle.getScaleFactor(context) : (widget.prefixIconSize - 10) * AppStyle.getScaleFactor(context), color: Color(0xff2e303a))),
),
);
}

@ -1,29 +1,28 @@
import 'package:test_sa/views/app_style/colors.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'app_icon_button.dart';
class ABackButton extends StatelessWidget {
final VoidCallback onPressed;
final IconData icon;
const ABackButton({Key key, this.onPressed,this.icon}) : super(key: key);
const ABackButton({Key key, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 4,
horizontal: 16
),
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
child: AIconButton(
color: AColors.white,
backgroundColor: AColors.green,
iconData: FontAwesomeIcons.reply,
backgroundColor: AColors.primaryColor,
iconData: icon ?? Icons.arrow_back_ios_new,
iconSize: 24,
buttonSize: 42,
onPressed: onPressed ?? (){
Navigator.of(context).pop();
},
buttonSize: 40,
onPressed: onPressed ??
() {
Navigator.of(context).pop();
},
),
);
}

@ -1,6 +1,6 @@
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:flutter/material.dart';
class AButton extends StatelessWidget {
final String text;
@ -10,40 +10,26 @@ class AButton extends StatelessWidget {
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, this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: color.computeLuminance() > 0.5
? AColors.black : Colors.white,
elevation: 0,
foregroundColor: color.computeLuminance() > 0.5 ? AColors.black : Colors.white,
backgroundColor: color,
padding: padding ?? const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.getBorderRadius(context)
)
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context))),
),
onPressed: onPressed,
child: Text(
text??"",
style: textStyle
?? Theme.of(context).textTheme.subtitle2.copyWith(
color: AColors.white,
fontSize: 18
),
text ?? "",
style: textStyle ?? Theme.of(context).textTheme.subtitle2.copyWith(color: AColors.white, fontSize: 14,fontWeight: FontWeight.w600),
textScaleFactor: AppStyle.getScaleFactor(context),
)
),
),
);
}

@ -1,6 +1,6 @@
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:flutter/material.dart';
class AOutLinedButton extends StatelessWidget {
final String text;
@ -9,42 +9,36 @@ class AOutLinedButton extends StatelessWidget {
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, this.text, this.padding, this.onPressed, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
return OutlinedButton(
style: ElevatedButton.styleFrom(
padding: padding ?? EdgeInsets.symmetric(vertical: 12),
textStyle: textStyle
?? Theme.of(context).textTheme.subtitle2.copyWith(
fontSize: 18
style: ElevatedButton.styleFrom(
padding: padding ?? EdgeInsets.symmetric(vertical: 12),
textStyle: textStyle ?? Theme
.of(context)
.textTheme
.subtitle2
.copyWith(fontSize: 18),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context))),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.getBorderRadius(context)
)
),
),
onPressed: onPressed,
child: Row(
children: [
Expanded(
child: Text(
text??"",
textAlign: TextAlign.center,
textScaleFactor: AppStyle.getScaleFactor(context),
onPressed: onPressed,
child: Row(
children: [
Expanded(
child: Text(
text ?? "",
style: Theme
.of(context)
.textTheme
.subtitle2
.copyWith(color: AColors.primaryColor, fontSize: 14, fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
),
],
)
);
],
));
}
}

@ -1,64 +1,50 @@
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 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class DepartmentButton extends StatelessWidget {
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;
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 12),
elevation: 0,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
side: BorderSide(
color: AColors.black
)
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
foregroundColor: AColors.primaryColor,
backgroundColor: AColors.white,
backgroundColor: AColors.inputFieldBackgroundColor,
),
child: Row(
children: [
FaIcon(
FontAwesomeIcons.hospitalUser,
size: 28,
color: AColors.black,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
department?.name ?? _subtitle.pickUnite,
style: Theme.of(context).textTheme.subtitle1,
style: Theme.of(context).textTheme.bodyText1,
textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
textAlign: TextAlign.left,
),
),
),
const Icon(Icons.keyboard_arrow_down, size: 28, color: AColors.grey3A),
],
),
onPressed: () async {
Department _department = await Navigator.of(context).pushNamed(SingleDepartmentPicker.id) as Department;
onDepartmentPick(_department);
}
);
});
}
}

@ -1,48 +1,39 @@
import 'package:test_sa/views/app_style/sizing.dart';
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';
class DrawerItem extends StatelessWidget {
final String title;
final IconData icon;
final VoidCallback onPressed;
const DrawerItem({Key key, this.title, this.icon, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(0.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.getBorderRadius(context)
)
),
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context))),
primary: Theme.of(context).colorScheme.onPrimary,
),
onPressed: onPressed,
child: Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 48,
child: Icon(
icon, color: Theme.of(context).colorScheme.primary
),
),
),
Icon(icon, color: AColors.grey3A,size: 20),
12.width,
Text(
title,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 16,
color: Theme.of(context).colorScheme.primary
),
style: Theme.of(context).textTheme.headline6.copyWith(fontSize: 14, color: AColors.grey3A),
textScaleFactor: AppStyle.getScaleFactor(context),
),
],
),
).paddingOnly(left: 20,right: 20),
),
);
}

@ -1,86 +1,78 @@
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 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class DeviceButton extends StatelessWidget {
final Function(Device) onDevicePick;
final Device device;
const DeviceButton({
Key key,
this.device,
this.onDevicePick
}) : super(key: key);
const DeviceButton({Key key, this.device, this.onDevicePick}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 16,vertical: device == null ? 12 : 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
side: BorderSide(
color: AColors.black
)
style: ElevatedButton.styleFrom(
elevation: 0,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: device == null ? 12 : 8),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
foregroundColor: AColors.primaryColor,
backgroundColor: AColors.inputFieldBackgroundColor,
),
onPrimary: AColors.primaryColor,
primary: AColors.white,
),
child: Row(
children: [
FaIcon(
FontAwesomeIcons.hardDrive,
size: 28,
color: AColors.black,
),
device == null ?
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text(
_subtitle.pickDevice,
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
),
),
):
Expanded(
child: ListTile(
title: Text("${_subtitle.sn} : " + device.serialNumber,
style: Theme.of(context).textTheme.subtitle1,
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(color: Theme.of(context).textTheme.subtitle1.color,),
Text("${_subtitle.brand} : " + device.brand,
style: Theme.of(context).textTheme.subtitle2,
device == null
? Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text(
_subtitle.pickDevice,
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
textAlign: TextAlign.left,
),
),
Divider(color: Theme.of(context).textTheme.subtitle1.color,),
Text("${_subtitle.model} : " + device.model,
style: Theme.of(context).textTheme.subtitle2,
)
: Expanded(
child: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
"${_subtitle.sn} : " + device.serialNumber,
style: Theme.of(context).textTheme.subtitle1,
),
],
),
)
)
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.brand} : " + device.brand,
style: Theme.of(context).textTheme.subtitle2,
),
Divider(
color: Theme.of(context).textTheme.subtitle1.color,
),
Text(
"${_subtitle.model} : " + device.model,
style: Theme.of(context).textTheme.subtitle2,
),
],
),
)),
const Icon(Icons.keyboard_arrow_down, size: 28, color: AColors.grey3A),
],
),
onPressed: () async {
Device _device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Device;
onDevicePick(_device);
}
);
});
}
}

@ -1,3 +1,6 @@
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';
@ -6,9 +9,7 @@ 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 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart';
class AutoCompleteField extends StatefulWidget {
final String initialValue;
final Function(String) onSearch;
@ -21,7 +22,6 @@ class AutoCompleteField extends StatefulWidget {
}
class _AutoCompleteFieldState extends State<AutoCompleteField> {
SettingProvider _settingProvider;
TextEditingController _controller;
@ -36,29 +36,26 @@ class _AutoCompleteFieldState extends State<AutoCompleteField> {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Container(
padding: EdgeInsets.symmetric(
horizontal: 16
),
padding: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color:AColors.black),
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
boxShadow: [
AppStyle.boxShadow
]
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
// boxShadow: [
// AppStyle.boxShadow
// ]
),
child: TypeAheadField<Hospital>(
textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.headline6,
onSubmitted: widget.onSave,
controller: _controller,
textAlign: TextAlign.center,
@ -70,15 +67,11 @@ class _AutoCompleteFieldState extends State<AutoCompleteField> {
enabledBorder: InputBorder.none,
),
textInputAction: TextInputAction.search,
onEditingComplete:(){
onEditingComplete: () {
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);
},
itemBuilder: (context, hospital) {
return HospitalItem(

@ -1,65 +1,48 @@
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 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class HospitalButton extends StatelessWidget {
final Function(Hospital) onHospitalPick;
final Hospital hospital;
const HospitalButton({
Key key,
this.hospital,
this.onHospitalPick
}) : super(key: key);
const HospitalButton({Key key, this.hospital, this.onHospitalPick}) : super(key: key);
@override
Widget build(BuildContext context) {
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: AColors.primaryColor,
backgroundColor: AColors.white,
padding: EdgeInsets.symmetric(horizontal: 16,vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
side: const BorderSide(
color: AColors.black
)
style: ElevatedButton.styleFrom(
elevation: 0,
foregroundColor: AColors.primaryColor,
backgroundColor: AColors.inputFieldBackgroundColor,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context))),
),
),
child: Row(
children: [
const FaIcon(
FontAwesomeIcons.solidHospital,
size: 28,
color: AColors.black,
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
hospital?.name ?? _subtitle.pickHospital,
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 14, color: AColors.grey3A),
// textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
textAlign: TextAlign.left,
),
),
),
const Icon(Icons.keyboard_arrow_down, size: 28, color: AColors.grey3A),
],
),
onPressed: () async {
Hospital _hospital = await Navigator.of(context).pushNamed(SingleHospitalPicker.id) as Hospital;
onHospitalPick(_hospital);
}
);
});
}
}

@ -1,160 +1,170 @@
import 'dart:io';
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 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
import 'multi_image_picker_item.dart';
class MultiImagesPicker extends StatefulWidget {
final String label;
final bool error;
final List<File> images;
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{
class _MultiImagesPickerState extends State<MultiImagesPicker> with TickerProviderStateMixin {
Size _size;
@override
Widget build(BuildContext context) {
_size = MediaQuery.of(context).size;
Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
Row(
children: [
Expanded(
child: Text(
widget.label ?? _subtitle.images,
style: Theme.of(context).textTheme
.headline6.copyWith(fontSize: 18,),
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
AFlatButton(
text: _subtitle.add,
onPressed: (){onImagePick(_subtitle);},
),
],
return Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
),
SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
AnimatedSize(
duration: Duration(milliseconds: 400),
child: !widget.error ? SizedBox.shrink() :
Column(
crossAxisAlignment: CrossAxisAlignment.start,
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
Row(
children: [
Text(
_subtitle.imagesRequired,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 14,
color: AColors.red,
Expanded(
child: Text(
widget.label ?? _subtitle.images,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 16,
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
AFlatButton(
text: _subtitle.add,
onPressed: () {
onImagePick(_subtitle);
},
),
],
),
),
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
child: Container(
key: ValueKey(widget.images.length),
width: _size.width,
height: 200 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(8 * AppStyle.getScaleFactor(context),),
alignment: Alignment.topLeft,
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).primaryColor,
width: 2
12.height,
AnimatedSize(
duration: Duration(milliseconds: 400),
child: !widget.error
? SizedBox.shrink()
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_subtitle.imagesRequired,
style: Theme.of(context).textTheme.headline6.copyWith(
fontSize: 14,
color: AColors.red,
),
textScaleFactor: AppStyle.getScaleFactor(context),
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
],
),
),
AnimatedSwitcher(
duration: Duration(milliseconds: 400),
child: Container(
key: ValueKey(widget.images.length),
width: _size.width,
height: 200 * AppStyle.getScaleFactor(context),
padding: EdgeInsets.all(
8 * AppStyle.getScaleFactor(context),
),
borderRadius: BorderRadius.circular(
8 * AppStyle.getScaleFactor(context)),
),
child: widget.images.isEmpty?
MaterialButton(
onPressed: (){onImagePick(_subtitle);},
child: Center(
child: Icon(
alignment: Alignment.topLeft,
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor, width: 2),
borderRadius: BorderRadius.circular(8 * AppStyle.getScaleFactor(context)),
),
child: widget.images.isEmpty
? MaterialButton(
onPressed: () {
onImagePick(_subtitle);
},
child: Center(
child: Icon(
Icons.add_a_photo_outlined,
size: 48 * AppStyle.getScaleFactor(context),
color: Theme.of(context).primaryColor,
size: 48 * AppStyle.getScaleFactor(context),
color: Theme.of(context).primaryColor,
)),
)
),
) :
GridView.count(
crossAxisCount: 2,//_size.width ~/ 80,
scrollDirection: Axis.horizontal,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(
widget.images.length,
(index) {
File _image = widget.images[index];
return MultiImagesPickerItem(
image: _image,
onRemoveTap: (image){
widget.images.remove(image);
setState(() {});
},
);
}
),
: GridView.count(
crossAxisCount: 2,
//_size.width ~/ 80,
scrollDirection: Axis.horizontal,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(widget.images.length, (index) {
File _image = widget.images[index];
return MultiImagesPickerItem(
image: _image,
onRemoveTap: (image) {
widget.images.remove(image);
setState(() {});
},
);
}),
),
),
),
),
],
],
),
);
}
onImagePick( Subtitle _subtitle) async {
if(widget.images.length >= 5){
onImagePick(Subtitle _subtitle) async {
if (widget.images.length >= 5) {
Fluttertoast.showToast(msg: _subtitle.maxImagesNumberIs5);
return;
}
ImageSource source = await showDialog(
context: context,
builder: (dialogContext) => CupertinoAlertDialog(
actions: <Widget>[
TextButton(
child: Text(_subtitle.pickFromCamera),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.camera);
},
),
TextButton(
child: Text(_subtitle.pickFromGallery),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.gallery);
},
),
],
)
);
if(source == null)
return;
actions: <Widget>[
TextButton(
child: Text(_subtitle.pickFromCamera),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.camera);
},
),
TextButton(
child: Text(_subtitle.pickFromGallery),
onPressed: () {
Navigator.of(dialogContext).pop(ImageSource.gallery);
},
),
],
));
if (source == null) return;
final pickedFile = await ImagePicker().pickImage(
source: source,
imageQuality: 70,
maxWidth: 800,
maxHeight: 800
);
final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 70, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
File _fileImage = File(pickedFile.path);
if(_fileImage != null){
if (_fileImage != null) {
widget.images.insert(0, _fileImage);
setState(() {});
}

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
class LandPageItem extends StatelessWidget {
class LandPageItem extends StatelessWidget {
final String text;
final IconData icon;
final VoidCallback onPressed;
@ -10,28 +11,34 @@ class LandPageItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(10 * AppStyle.getScaleFactor(context),),
textStyle: Theme.of(context).textTheme.subtitle2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
AppStyle.getBorderRadius(context)
)
),
//foregroundColor: Colors.white,
return InkWell(
onTap: onPressed,
child: Container(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.15),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
onPressed: onPressed,
child: Column(
children: [
Expanded(
child: Center(
child: Icon(icon,size: 58 * AppStyle.getScaleFactor(context),)
),
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(
icon,
color: AColors.primaryColor,
size: 42 * AppStyle.getScaleFactor(context),
),
Text(text,textAlign: TextAlign.center,),
Text(text, style: TextStyle(color: AColors.grey3A)),
],
)
),
),
);
}
}

@ -3,22 +3,22 @@ import 'package:flutter/services.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rive/rive.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/sound/sound_player.dart';
import '../../app_style/sizing.dart';
class RecordSound extends StatefulWidget {
final Function(String) onRecord;
const RecordSound({Key key,@required this.onRecord}) : super(key: key);
const RecordSound({Key key, @required this.onRecord}) : super(key: key);
@override
State<RecordSound> createState() => _RecordSoundState();
}
class _RecordSoundState extends State<RecordSound> {
FlutterSoundRecorder _myRecorder = FlutterSoundRecorder();
bool _recorderIsOpened = false;
bool _recording = false;
@ -28,8 +28,9 @@ class _RecordSoundState extends State<RecordSound> {
@override
void setState(VoidCallback fn) {
if(mounted) super.setState(fn);
if (mounted) super.setState(fn);
}
@override
void initState() {
super.initState();
@ -41,7 +42,7 @@ class _RecordSoundState extends State<RecordSound> {
// Load the animation file from the bundle, note that you could also
// download this. The RiveFile just expects a list of bytes.
rootBundle.load('assets/rives/recording.riv').then(
(data) async {
(data) async {
// Load the RiveFile from the binary data.
final file = RiveFile.import(data);
// The artboard is the root of the animation and gets drawn in the
@ -53,10 +54,8 @@ class _RecordSoundState extends State<RecordSound> {
_rive = artboard;
setState(() {});
},
);
}
@override
@ -71,21 +70,16 @@ class _RecordSoundState extends State<RecordSound> {
_fastTab = false;
// await Permission.camera
PermissionStatus status = await Permission.microphone.request();
if(!status.isGranted){
if (!status.isGranted) {
return;
}
_rive.addController(SimpleAnimation('recording'));
if(!_recorderIsOpened){
if (!_recorderIsOpened) {
await _myRecorder.openRecorder();
_recorderIsOpened = true;
}
await _myRecorder.startRecorder(
toFile: "record_${DateTime.now().millisecondsSinceEpoch}.mp4",
codec: Codec.aacMP4,
sampleRate: 360000,
bitRate: 360000
);
await _myRecorder.startRecorder(toFile: "record_${DateTime.now().millisecondsSinceEpoch}.mp4", codec: Codec.aacMP4, sampleRate: 360000, bitRate: 360000);
_recording = true;
setState(() {});
@ -93,7 +87,7 @@ class _RecordSoundState extends State<RecordSound> {
}
_stopRecording() async {
if(!_recording){
if (!_recording) {
_fastTab = true;
setState(() {});
return;
@ -103,12 +97,12 @@ class _RecordSoundState extends State<RecordSound> {
_record = path;
widget.onRecord(path);
_recording = false;
setState(() { });
setState(() {});
print("onTapUp");
}
_cancelRecording() async {
if(!_recording) return;
if (!_recording) return;
String path = await _myRecorder.stopRecorder();
_myRecorder.deleteRecord(fileName: path);
_rive.addController(SimpleAnimation('delete'));
@ -116,86 +110,98 @@ class _RecordSoundState extends State<RecordSound> {
// rebuild();
_recording = false;
await Future.delayed(const Duration(seconds: 1));
if(!_recording) setState(() { });
if (!_recording) setState(() {});
print("onTapCancel");
// _message.memoryAudio.;
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Expanded(
child: _recording ?
Row(
children: [
ASmallButton(
text: "done",
onPressed: (){
_stopRecording();
},
),
Expanded(
child: Stack(
children: [
SizedBox(
height: 24 * AppStyle.getScaleFactor(context),
child: Rive(artboard: _rive,)
),
InkWell(
child: SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
width: MediaQuery.of(context).size.width,
return Container(
padding: EdgeInsets.only(left: 12, right: 0),
decoration: BoxDecoration(
color: Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Column(
children: [
Row(
children: [
Expanded(
child: _recording
? Row(
children: [
ASmallButton(
text: "done",
onPressed: () {
_stopRecording();
},
),
onTap: (){
_cancelRecording();
},
),
],
),
),
],
): _record != null
? Row(
children: [
Expanded(child: ASoundPlayer(audio: _record)),
AIconButton2(
iconData: Icons.delete,
onPressed: (){
widget.onRecord(null);
_record = null;
setState(() { });
},
Expanded(
child: Stack(
children: [
SizedBox(
height: 24 * AppStyle.getScaleFactor(context),
child: Rive(
artboard: _rive,
)),
InkWell(
child: SizedBox(
height: 32 * AppStyle.getScaleFactor(context),
width: MediaQuery.of(context).size.width,
),
onTap: () {
_cancelRecording();
},
),
],
),
),
],
)
],
)
: const Text("Record Voice"),
),
Material(
color: Colors.transparent,
child: GestureDetector(
//key: ValueKey("voice"),
child: const Padding(
padding: EdgeInsets.all(16.0),
child: Icon(Icons.mic),
),
: _record != null
? Row(
children: [
Expanded(child: ASoundPlayer(audio: _record)),
AIconButton2(
iconData: Icons.delete,
onPressed: () {
widget.onRecord(null);
_record = null;
setState(() {});
},
)
],
)
: const Text("Record Voice"),
),
Material(
color: Colors.transparent,
child: GestureDetector(
//key: ValueKey("voice"),
child: const Padding(
padding: EdgeInsets.all(12.0),
child: Icon(Icons.mic),
),
onTapDown: (TapDownDetails details) async {
_startRecording();
},
onTapUp: (TapUpDetails details) async {
_stopRecording();
},
onTapCancel: () async {
_cancelRecording();
},
onTapDown: (TapDownDetails details) async {
_startRecording();
},
onTapUp: (TapUpDetails details) async {
_stopRecording();
},
onTapCancel: () async {
_cancelRecording();
},
),
),
),
],
),
],
],
),
],
),
);
}
}

@ -1,22 +1,19 @@
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../app_text_form_field.dart';
class SpeechToTextButton extends StatefulWidget {
final TextEditingController controller;
final bool mini;
const SpeechToTextButton({
Key key, this.controller,this.mini = false
}) : super(key: key);
const SpeechToTextButton({Key key, this.controller, this.mini = false}) : super(key: key);
@override
_SpeechToTextButtonState createState() => _SpeechToTextButtonState();
@ -32,7 +29,7 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
_speechEnabled = await _speechToText.initialize(
onError: (SpeechRecognitionError error) async {
Fluttertoast.showToast(msg: "failed to convert text to speech");
setState(() { });
setState(() {});
},
);
}
@ -40,18 +37,17 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
/// Each time to start a speech recognition session
void _startListening() async {
_speechEnabled = _speechToText.isAvailable;
if(_speechToText.isListening){
if (_speechToText.isListening) {
Fluttertoast.showToast(msg: "Currently in use");
return;
}
if(!_speechEnabled) return;
if (!_speechEnabled) return;
await _speechToText.listen(
onResult: (SpeechRecognitionResult result){
widget.controller.text = result.recognizedWords;
setState(() {});
},
localeId: _settingProvider.speechToText
);
onResult: (SpeechRecognitionResult result) {
widget.controller.text = result.recognizedWords;
setState(() {});
},
localeId: _settingProvider.speechToText);
setState(() {});
}
@ -72,51 +68,66 @@ class _SpeechToTextButtonState extends State<SpeechToTextButton> {
@override
void setState(VoidCallback fn) {
if(!this.mounted) return;
if (!this.mounted) return;
super.setState(fn);
}
@override
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
return Row(
children: [
widget.mini ? SizedBox.shrink() :
ASubTitle("Text To Speech"),
widget.controller.text.isNotEmpty?
AIconButton2(
iconData: Icons.delete,
onPressed: (){
widget.controller.clear();
setState(() {});
},
):SizedBox.shrink(),
Spacer(),
TextButton(
onPressed: (){
if(_speechToText.isListening) return;
if(_settingProvider.speechToText == "ar"){
_settingProvider.setSpeechToText("en");
} else{
_settingProvider.setSpeechToText("ar");
}
},
child: Text(_settingProvider.speechToText)
return Container(
padding: EdgeInsets.only(left: 12, right: 12),
decoration: BoxDecoration(
color: Color(0xfff5f5f5),
border: Border.all(
color: Color(0xffefefef),
),
GestureDetector(
child: _speechToText.isListening
? Icon(Icons.fiber_manual_record,color: Colors.red,)
: Icon(Icons.mic,color: Theme.of(context).colorScheme.primary,),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
),
child: Row(
children: [
widget.mini ? SizedBox.shrink() : ASubTitle("Text To Speech"),
widget.controller.text.isNotEmpty
? AIconButton2(
iconData: Icons.delete,
onPressed: () {
widget.controller.clear();
setState(() {});
},
)
: SizedBox.shrink(),
Spacer(),
TextButton(
onPressed: () {
if (_speechToText.isListening) return;
onTap: () async {
if(!_speechEnabled){
Fluttertoast.showToast(msg: "microphone not available");
return;
}
_startListening();
},
),
],
if (_settingProvider.speechToText == "ar") {
_settingProvider.setSpeechToText("en");
} else {
_settingProvider.setSpeechToText("ar");
}
},
child: Text(_settingProvider.speechToText)),
GestureDetector(
child: _speechToText.isListening
? Icon(
Icons.fiber_manual_record,
color: Colors.red,
)
: Icon(
Icons.mic,
color: Theme.of(context).colorScheme.primary,
),
onTap: () async {
if (!_speechEnabled) {
Fluttertoast.showToast(msg: "microphone not available");
return;
}
_startListening();
},
),
],
),
);
}
}

@ -1,28 +1,28 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/status.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:flutter/material.dart';
class SingleStatusMenu extends StatefulWidget {
final List<Status> statuses;
final Status initialStatus;
final Function(Status) onSelect;
const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key);
@override
_SingleStatusMenuState createState() => _SingleStatusMenuState();
}
class _SingleStatusMenuState extends State<SingleStatusMenu> {
Status _selectedStatus;
@override
void didUpdateWidget(covariant SingleStatusMenu oldWidget) {
if(widget.initialStatus != null){
_selectedStatus = widget.statuses?.firstWhere(
(element) {
return element?.id == widget.initialStatus.id;
});
if (widget.initialStatus != null) {
_selectedStatus = widget.statuses?.firstWhere((element) {
return element?.id == widget.initialStatus.id;
});
} else {
_selectedStatus = null;
}
@ -31,43 +31,40 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
@override
void initState() {
if(widget.initialStatus != null){
_selectedStatus = widget.statuses?.firstWhere(
(element) {
return element?.id == widget.initialStatus.id;
});
if (widget.initialStatus != null) {
_selectedStatus = widget.statuses?.firstWhere((element) {
return element?.id == widget.initialStatus.id;
});
}
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 16
),
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color:AColors.black),
borderRadius: BorderRadius.circular(
AppStyle.borderRadius * AppStyle.getScaleFactor(context)
),
boxShadow: const [
AppStyle.boxShadow
]
color: AColors.inputFieldBackgroundColor,
border: Border.all(
color: Color(0xffefefef),
),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
// boxShadow: const [
// AppStyle.boxShadow
// ]
),
child: DropdownButton<Status>(
value: _selectedStatus,
iconSize: 24,
elevation: 16,
icon: Icon(Icons.keyboard_arrow_down_rounded),
elevation: 0,
isExpanded: true,
hint: Text(
"Select",
style: Theme.of(context).textTheme.subtitle1,
),
style: TextStyle(
color: Theme.of(context).primaryColor
),
style: TextStyle(color: Theme.of(context).primaryColor),
underline: SizedBox.shrink(),
onChanged: (Status newValue) {
setState(() {
@ -75,21 +72,15 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
});
widget.onSelect(newValue);
},
items: widget.statuses
.map<DropdownMenuItem<Status>>((Status value) {
items: widget.statuses.map<DropdownMenuItem<Status>>((Status value) {
return DropdownMenuItem<Status>(
value: value,
child: Text(
value.label,
style: Theme.of(context).textTheme.subtitle1.copyWith(
color: Theme.of(context).primaryColor,
fontSize: 11,
//fontWeight: FontWeight.bold
),
value.label,
style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).primaryColor, fontWeight: FontWeight.w600),
),
);
})
.toList(),
}).toList(),
),
);
}

@ -12,7 +12,7 @@ class ASubTitle extends StatelessWidget {
padding: padding ?? EdgeInsets.zero,
child: Text(
text,
style: Theme.of(context).textTheme.subtitle2.copyWith(
style: Theme.of(context).textTheme.bodyText1.copyWith(
// fontWeight: FontWeight.bold,
fontSize: font,
color: color

@ -92,7 +92,7 @@ flutter:
- assets/subtitles/
- assets/rives/
fonts:
- family: Swiss
- family: Swiss
fonts:
- asset: assets/fonts/Gotham_Rounded_Light.otf
weight: 300
@ -100,3 +100,23 @@ flutter:
weight: 400
- asset: assets/fonts/Gotham_Rounded_Bold.otf
weight: 700
- family: Poppins
fonts:
- asset: assets/fonts/poppins/Poppins-Black.ttf
weight: 900
- asset: assets/fonts/poppins/Poppins-ExtraBold.ttf
weight: 800
- asset: assets/fonts/poppins/Poppins-Bold.ttf
weight: 700
- asset: assets/fonts/poppins/Poppins-SemiBold.ttf
weight: 600
- asset: assets/fonts/poppins/Poppins-Medium.ttf
weight: 500
- asset: assets/fonts/poppins/Poppins-Regular.ttf
weight: 400
- asset: assets/fonts/poppins/Poppins-Light.ttf
weight: 300
- asset: assets/fonts/poppins/Poppins-ExtraLight.ttf
weight: 200
- asset: assets/fonts/poppins/Poppins-Thin.ttf
weight: 100
Loading…
Cancel
Save