forked from yaso_meth/mih-project
Merge pull request #198 from yaso-meth/NEW--UX-Option-Selection
NEW--UX-Option-Selection
This commit is contained in:
@@ -54,6 +54,27 @@ class MihValidationServices {
|
||||
return "Let's create a great username for you!$errorMessage";
|
||||
}
|
||||
|
||||
String? validateNumber(String? number, int? minValue, int? maxValue) {
|
||||
String? errorMessage = "";
|
||||
if (number == null || number.isEmpty) {
|
||||
errorMessage += "This field is required";
|
||||
return errorMessage;
|
||||
}
|
||||
int? value = int.tryParse(number);
|
||||
if (value == null) {
|
||||
errorMessage += "Please enter a valid number";
|
||||
return errorMessage;
|
||||
}
|
||||
if (value < (minValue ?? 0)) {
|
||||
errorMessage += "Value must be >= ${minValue ?? 0}";
|
||||
}
|
||||
if (maxValue != null && value > maxValue) {
|
||||
if (errorMessage.isNotEmpty) errorMessage += "\n";
|
||||
errorMessage += "Value must be <= $maxValue";
|
||||
}
|
||||
return errorMessage.isEmpty ? null : errorMessage;
|
||||
}
|
||||
|
||||
String? validatePassword(String? password) {
|
||||
String? errorMessage = "";
|
||||
if (password == null || password.isEmpty) {
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
|
||||
class Medcertinput extends StatefulWidget {
|
||||
final TextEditingController startDateController;
|
||||
final TextEditingController endDateTextController;
|
||||
final TextEditingController retDateTextController;
|
||||
const Medcertinput({
|
||||
super.key,
|
||||
required this.startDateController,
|
||||
required this.endDateTextController,
|
||||
required this.retDateTextController,
|
||||
});
|
||||
|
||||
@override
|
||||
State<Medcertinput> createState() => _MedcertinputState();
|
||||
}
|
||||
|
||||
class _MedcertinputState extends State<Medcertinput> {
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
//height: 325,
|
||||
child: Column(
|
||||
children: [
|
||||
//const SizedBox(height: 50.0),
|
||||
SizedBox(
|
||||
width: 700,
|
||||
child: MIHDateField(
|
||||
controller: widget.startDateController,
|
||||
lableText: "From",
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
SizedBox(
|
||||
width: 700,
|
||||
child: MIHDateField(
|
||||
controller: widget.endDateTextController,
|
||||
lableText: "Up to Including",
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
SizedBox(
|
||||
width: 700,
|
||||
child: MIHDateField(
|
||||
controller: widget.retDateTextController,
|
||||
lableText: "Return",
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHDateField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String lableText;
|
||||
final bool required;
|
||||
|
||||
const MIHDateField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.lableText,
|
||||
required this.required,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHDateField> createState() => _MIHDateFieldState();
|
||||
}
|
||||
|
||||
class _MIHDateFieldState extends State<MIHDateField> {
|
||||
final FocusNode _focus = FocusNode();
|
||||
bool startup = true;
|
||||
// bool makeEditable() {
|
||||
Future<void> _selectDate(BuildContext context) async {
|
||||
DateTime? picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() {
|
||||
widget.controller.text = picked.toString().split(" ")[0];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.lableText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.lableText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.lableText} is required";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
controller: widget.controller,
|
||||
readOnly: true,
|
||||
obscureText: false,
|
||||
focusNode: _focus,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
label: setRequiredText(),
|
||||
//labelText: widget.lableText,
|
||||
//labelStyle: const TextStyle(color: Colors.blueAccent),
|
||||
prefixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
_selectDate(context);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHDropdownField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool required;
|
||||
final List<String> dropdownOptions;
|
||||
// final void Function(String?)? onSelect;
|
||||
final bool editable;
|
||||
final bool enableSearch;
|
||||
|
||||
const MIHDropdownField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.dropdownOptions,
|
||||
required this.required,
|
||||
required this.editable,
|
||||
required this.enableSearch,
|
||||
// this.onSelect,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHDropdownField> createState() => _MIHDropdownFieldState();
|
||||
}
|
||||
|
||||
class _MIHDropdownFieldState extends State<MIHDropdownField> {
|
||||
//var dropbownItems = ["Dr.", "Assistant"];
|
||||
bool startup = true;
|
||||
final FocusNode _focus = FocusNode();
|
||||
late List<DropdownMenuEntry<String>> menu;
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
// widget.onSelect;
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<DropdownMenuEntry<String>> buidMenueOptions(List<String> options) {
|
||||
List<DropdownMenuEntry<String>> menueList = [];
|
||||
for (final i in options) {
|
||||
menueList.add(DropdownMenuEntry(
|
||||
value: i,
|
||||
label: i,
|
||||
style: ButtonStyle(
|
||||
foregroundColor: WidgetStatePropertyAll(
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor()))));
|
||||
}
|
||||
return menueList;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
menu = buidMenueOptions(widget.dropdownOptions);
|
||||
_focus.addListener(_onFocusChange);
|
||||
_focus.canRequestFocus = widget.enableSearch;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
// bool makeEditable() {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DropdownMenu(
|
||||
enableSearch: widget.enableSearch,
|
||||
enableFilter: widget.enableSearch,
|
||||
// requestFocusOnTap: true,
|
||||
initialSelection: widget.controller.text,
|
||||
enabled: widget.editable,
|
||||
trailingIcon: Icon(
|
||||
Icons.arrow_drop_down,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
selectedTrailingIcon: Icon(
|
||||
Icons.arrow_drop_up,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
menuHeight: 300,
|
||||
controller: widget.controller,
|
||||
expandedInsets: EdgeInsets.zero,
|
||||
label: setRequiredText(),
|
||||
errorText: _errorText,
|
||||
|
||||
focusNode: _focus,
|
||||
onSelected: (selected) {
|
||||
_onFocusChange();
|
||||
// if (widget.editable == false) {
|
||||
// return false;
|
||||
// }
|
||||
},
|
||||
leadingIcon: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
widget.controller.clear();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.delete_outline_rounded,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
menuStyle: MenuStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor()),
|
||||
side: WidgetStatePropertyAll(
|
||||
BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0),
|
||||
),
|
||||
),
|
||||
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
outlineBorder: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
dropdownMenuEntries: menu,
|
||||
// const <DropdownMenuEntry<String>>[
|
||||
// DropdownMenuEntry(value: "Dr.", label: "Dr."),
|
||||
// DropdownMenuEntry(value: "Assistant", label: "Assistant"),
|
||||
// ],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// filled: true,
|
||||
// hintText: hintText,
|
||||
// hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
// enabledBorder: const OutlineInputBorder(
|
||||
// borderSide: BorderSide(
|
||||
// color: Colors.blueAccent,
|
||||
// width: 2.0,
|
||||
// ),
|
||||
// ),
|
||||
// focusedBorder: const OutlineInputBorder(
|
||||
// borderSide: BorderSide(color: Colors.blue),
|
||||
@@ -1,177 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHFileField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool editable;
|
||||
final bool required;
|
||||
final void Function() onPressed;
|
||||
|
||||
const MIHFileField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.editable,
|
||||
required this.required,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHFileField> createState() => _MIHFileFieldState();
|
||||
}
|
||||
|
||||
class _MIHFileFieldState extends State<MIHFileField> {
|
||||
bool startup = true;
|
||||
final FocusNode _focus = FocusNode();
|
||||
|
||||
bool makeEditable() {
|
||||
if (widget.editable) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
String errorMessage = '';
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
if (widget.hintText == "Email" && !isEmailValid(text)) {
|
||||
errorMessage += "Enter a valid email address\n";
|
||||
}
|
||||
if (widget.hintText == "Username" && text.length < 8) {
|
||||
errorMessage += "• Username must contain at least 8 characters.\n";
|
||||
}
|
||||
if (widget.hintText == "Username" && !isUsernameValid(text)) {
|
||||
errorMessage += "• Username can only contain '_' special Chracters.\n";
|
||||
}
|
||||
if (errorMessage.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
// If there are no error messages, the password is valid
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
bool isUsernameValid(String username) {
|
||||
return RegExp(r'^(?=[a-zA-Z0-9._]{8,20}$)(?!.*[_.]{2})[^_.].*[^_.]$')
|
||||
.hasMatch(username);
|
||||
}
|
||||
|
||||
bool isEmailValid(String email) {
|
||||
return RegExp(r'^[\w-\.]+@[a-zA-Z]+\.[a-zA-Z]{2,}$').hasMatch(email);
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
controller: widget.controller,
|
||||
focusNode: _focus,
|
||||
readOnly: makeEditable(),
|
||||
//enabled: !makeEditable(),
|
||||
obscureText: false,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.attach_file),
|
||||
onPressed: widget.onPressed,
|
||||
),
|
||||
label: setRequiredText(),
|
||||
//labelStyle: TextStyle(color: MzanziInnovationHub.of(context)!.theme.primaryColor()),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
//errorBorder: const InputBorder(),
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHMLTextField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool editable;
|
||||
final bool required;
|
||||
|
||||
const MIHMLTextField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.editable,
|
||||
required this.required,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHMLTextField> createState() => _MIHMLTextFieldState();
|
||||
}
|
||||
|
||||
class _MIHMLTextFieldState extends State<MIHMLTextField> {
|
||||
bool startup = true;
|
||||
final FocusNode _focus = FocusNode();
|
||||
|
||||
bool makeEditable() {
|
||||
if (widget.editable) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
textAlign: TextAlign.start,
|
||||
textAlignVertical: TextAlignVertical.top,
|
||||
expands: true,
|
||||
maxLines: null,
|
||||
controller: widget.controller,
|
||||
readOnly: makeEditable(),
|
||||
obscureText: false,
|
||||
focusNode: _focus,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
label: setRequiredText(),
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
labelStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
alignLabelWithHint: true,
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHNumberField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool editable;
|
||||
final bool required;
|
||||
final bool enableDecimal;
|
||||
final Iterable<String>? autoFillHintGroup;
|
||||
|
||||
const MIHNumberField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.editable,
|
||||
required this.required,
|
||||
required this.enableDecimal,
|
||||
this.autoFillHintGroup,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHNumberField> createState() => _MIHNumberFieldState();
|
||||
}
|
||||
|
||||
class _MIHNumberFieldState extends State<MIHNumberField> {
|
||||
bool startup = true;
|
||||
final FocusNode _focus = FocusNode();
|
||||
|
||||
List<TextInputFormatter> allowDecimals() {
|
||||
if (widget.enableDecimal) {
|
||||
return <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.\d*)?')),
|
||||
];
|
||||
} else {
|
||||
return [FilteringTextInputFormatter.digitsOnly];
|
||||
}
|
||||
}
|
||||
|
||||
bool makeEditable() {
|
||||
if (widget.editable) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
String errorMessage = '';
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
if (widget.hintText == "Email" && !isEmailValid(text)) {
|
||||
errorMessage += "Enter a valid email address\n";
|
||||
}
|
||||
// if (widget.hintText == "Username" && text.length < 8) {
|
||||
// errorMessage += "• Username must contain at least 8 characters.\n";
|
||||
// }
|
||||
if (widget.hintText == "Username" && !isUsernameValid(text)) {
|
||||
errorMessage += "Let's create a great username for you!\n";
|
||||
errorMessage += "• Your username should start with a letter.\n";
|
||||
errorMessage += "• You can use letters, numbers, and/ or underscores.\n";
|
||||
errorMessage += "• Keep it between 6 and 30 characters.\n";
|
||||
errorMessage += "• Avoid special characters like @, #, or \$.\"\n";
|
||||
}
|
||||
if (errorMessage.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
// If there are no error messages, the password is valid
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
bool isUsernameValid(String username) {
|
||||
return RegExp(r'^[a-zA-Z][a-zA-Z0-9_]{5,19}$').hasMatch(username);
|
||||
}
|
||||
|
||||
bool isEmailValid(String email) {
|
||||
var regex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
|
||||
return regex.hasMatch(email);
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
// List<AutofillGroup> getAutoFillDetails(){
|
||||
// if(widget.autoFillHintGroup == null){
|
||||
// return [];
|
||||
// }
|
||||
// else{
|
||||
// return widget.autoFillHintGroup!;
|
||||
// }
|
||||
// }
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: allowDecimals(),
|
||||
autofillHints: widget.autoFillHintGroup,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
controller: widget.controller,
|
||||
focusNode: _focus,
|
||||
readOnly: makeEditable(),
|
||||
//enabled: !makeEditable(),
|
||||
obscureText: false,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
label: setRequiredText(),
|
||||
//labelStyle: TextStyle(color: MzanziInnovationHub.of(context)!.theme.primaryColor()),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
//errorBorder: const InputBorder(),
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHPassField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool required;
|
||||
final bool signIn;
|
||||
final Iterable<String>? autoFillHintGroup;
|
||||
final TextInputAction? textInputAction;
|
||||
|
||||
const MIHPassField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.required,
|
||||
required this.signIn,
|
||||
this.autoFillHintGroup,
|
||||
this.textInputAction,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHPassField> createState() => _MIHPassFieldState();
|
||||
}
|
||||
|
||||
class _MIHPassFieldState extends State<MIHPassField> {
|
||||
bool startup = true;
|
||||
final textFieldFocusNode = FocusNode();
|
||||
bool _obscured = true;
|
||||
//bool valid = false;
|
||||
|
||||
void _toggleObscured() {
|
||||
setState(() {
|
||||
_obscured = !_obscured;
|
||||
if (textFieldFocusNode.hasPrimaryFocus) {
|
||||
return; // If focus is on text field, dont unfocus
|
||||
}
|
||||
textFieldFocusNode.canRequestFocus =
|
||||
false; // Prevents focus if tap on eye
|
||||
});
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
String errorMessage = '';
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
// Password length greater than 8
|
||||
if (text.length <= 8 && !widget.signIn) {
|
||||
errorMessage += '• Password must contain at least 8 characters.\n';
|
||||
}
|
||||
|
||||
// Contains at least one uppercase letter
|
||||
if (!text.contains(RegExp(r'[A-Z]')) && !widget.signIn) {
|
||||
errorMessage += '• Uppercase letter is missing.\n';
|
||||
}
|
||||
|
||||
// Contains at least one lowercase letter
|
||||
if (!text.contains(RegExp(r'[a-z]')) && !widget.signIn) {
|
||||
errorMessage += '• Lowercase letter is missing.\n';
|
||||
}
|
||||
|
||||
// Contains at least one digit
|
||||
if (!text.contains(RegExp(r'[0-9]')) && !widget.signIn) {
|
||||
errorMessage += '• number is missing.\n';
|
||||
}
|
||||
|
||||
// Contains at least one special character
|
||||
if (!text.contains(RegExp(r'[!@#$%^&*]')) && !widget.signIn) {
|
||||
errorMessage += '• Special character is missing - !@#\$%^&*\n';
|
||||
}
|
||||
|
||||
// Contains no errors
|
||||
if (errorMessage.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
// If there are no error messages, the password is valid
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
textFieldFocusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
textFieldFocusNode.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
autofillHints: widget.autoFillHintGroup,
|
||||
textInputAction: widget.textInputAction,
|
||||
controller: widget.controller,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
obscureText: _obscured,
|
||||
focusNode: textFieldFocusNode,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
label: setRequiredText(),
|
||||
//labelStyle: const TextStyle(color: Colors.blueAccent),
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
//hintText: widget.hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
child: GestureDetector(
|
||||
onTap: _toggleObscured,
|
||||
child: Icon(
|
||||
_obscured
|
||||
? Icons.visibility_rounded
|
||||
: Icons.visibility_off_rounded,
|
||||
size: 24,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHTextField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool editable;
|
||||
final bool required;
|
||||
final TextInputAction? textInputAction;
|
||||
final Iterable<String>? autoFillHintGroup;
|
||||
|
||||
const MIHTextField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.editable,
|
||||
required this.required,
|
||||
this.autoFillHintGroup,
|
||||
this.textInputAction,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHTextField> createState() => _MIHTextFieldState();
|
||||
}
|
||||
|
||||
class _MIHTextFieldState extends State<MIHTextField> {
|
||||
bool startup = true;
|
||||
final FocusNode _focus = FocusNode();
|
||||
|
||||
bool makeEditable() {
|
||||
if (widget.editable) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
String errorMessage = '';
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
if (widget.hintText == "Email" && !isEmailValid(text)) {
|
||||
errorMessage += "Enter a valid email address\n";
|
||||
}
|
||||
// if (widget.hintText == "Username" && text.length < 8) {
|
||||
// errorMessage += "• Username must contain at least 8 characters.\n";
|
||||
// }
|
||||
if (widget.hintText == "Username" && !isUsernameValid(text)) {
|
||||
errorMessage += "Let's create a great username for you!\n";
|
||||
errorMessage += "• Your username should start with a letter.\n";
|
||||
errorMessage += "• You can use letters, numbers, and/ or underscores.\n";
|
||||
errorMessage += "• Keep it between 6 and 30 characters.\n";
|
||||
errorMessage += "• Avoid special characters like @, #, or \$.\"\n";
|
||||
}
|
||||
if (errorMessage.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
// If there are no error messages, the password is valid
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
bool isUsernameValid(String username) {
|
||||
return RegExp(r'^[a-zA-Z][a-zA-Z0-9_]{5,19}$').hasMatch(username);
|
||||
}
|
||||
|
||||
bool isEmailValid(String email) {
|
||||
var regex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
|
||||
return regex.hasMatch(email);
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
// List<AutofillGroup> getAutoFillDetails(){
|
||||
// if(widget.autoFillHintGroup == null){
|
||||
// return [];
|
||||
// }
|
||||
// else{
|
||||
// return widget.autoFillHintGroup!;
|
||||
// }
|
||||
// }
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
autofillHints: widget.autoFillHintGroup,
|
||||
textInputAction: widget.textInputAction,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
controller: widget.controller,
|
||||
focusNode: _focus,
|
||||
readOnly: makeEditable(),
|
||||
//enabled: !makeEditable(),
|
||||
obscureText: false,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
label: setRequiredText(),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHTimeField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String lableText;
|
||||
final bool required;
|
||||
|
||||
const MIHTimeField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.lableText,
|
||||
required this.required,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHTimeField> createState() => _MIHDateFieldState();
|
||||
}
|
||||
|
||||
class _MIHDateFieldState extends State<MIHTimeField> {
|
||||
final FocusNode _focus = FocusNode();
|
||||
bool startup = true;
|
||||
|
||||
Future<void> _selectTime(BuildContext context) async {
|
||||
TimeOfDay? picked = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: TimeOfDay.now(),
|
||||
builder: (context, child) {
|
||||
return MediaQuery(
|
||||
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
|
||||
child: child as Widget,
|
||||
);
|
||||
},
|
||||
);
|
||||
if (picked != null) {
|
||||
String hours = "";
|
||||
String minutes = "";
|
||||
setState(() {
|
||||
if (picked.hour <= 9) {
|
||||
hours = "0${picked.hour}";
|
||||
} else {
|
||||
hours = "${picked.hour}";
|
||||
}
|
||||
|
||||
if (picked.minute <= 9) {
|
||||
minutes = "0${picked.minute}";
|
||||
} else {
|
||||
minutes = "${picked.minute}";
|
||||
}
|
||||
|
||||
widget.controller.text = "$hours:$minutes";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.lableText,
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor())),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.lableText,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.lableText} is required";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
controller: widget.controller,
|
||||
readOnly: true,
|
||||
obscureText: false,
|
||||
focusNode: _focus,
|
||||
onChanged: (_) => setState(() {
|
||||
startup = false;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
errorText: _errorText,
|
||||
errorStyle: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
fontWeight: FontWeight.bold),
|
||||
label: setRequiredText(),
|
||||
//labelText: widget.lableText,
|
||||
//labelStyle: const TextStyle(color: Colors.blueAccent),
|
||||
prefixIcon: Icon(
|
||||
Icons.access_alarm,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
filled: true,
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
_selectTime(context);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,21 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_numeric_stepper.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_radio_options.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
|
||||
class PackageToolOne extends StatefulWidget {
|
||||
const PackageToolOne({super.key});
|
||||
@@ -35,6 +41,12 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
TextEditingController _textFieldTwoController = TextEditingController();
|
||||
TextEditingController _textFieldThreeController = TextEditingController();
|
||||
TextEditingController _textFieldFourController = TextEditingController();
|
||||
TextEditingController _textFieldFiveController = TextEditingController();
|
||||
TextEditingController _textFieldSixController = TextEditingController();
|
||||
TextEditingController _textFieldSevenController = TextEditingController();
|
||||
TextEditingController _textFieldEightController = TextEditingController();
|
||||
TextEditingController _textFieldNineController = TextEditingController();
|
||||
bool switchpositioin = true;
|
||||
final FocusNode searchFocusNode = FocusNode();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@@ -220,6 +232,83 @@ class _PackageToolOneState extends State<PackageToolOne> {
|
||||
: null,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihNumericStepper(
|
||||
controller: _textFieldFiveController,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
inputColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
hintText: "Number Stepper",
|
||||
requiredText: true,
|
||||
minValue: 1,
|
||||
maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihToggle(
|
||||
hintText: "Toggle",
|
||||
initialPostion: switchpositioin,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
readOnly: false,
|
||||
onChange: (value) {
|
||||
setState(() {
|
||||
switchpositioin = value;
|
||||
});
|
||||
print("Toggle Value: $switchpositioin");
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihRadioOptions(
|
||||
controller: _textFieldSixController,
|
||||
hintText: "Radio Options",
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
requiredText: true,
|
||||
radioOptions: const ["Option 1", "Option 2"],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihDropdownField(
|
||||
controller: _textFieldNineController,
|
||||
hintText: "Dropdown",
|
||||
dropdownOptions: const [
|
||||
"Option 1",
|
||||
"Option 2",
|
||||
"Option 3",
|
||||
],
|
||||
editable: true,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihDateField(
|
||||
controller: _textFieldSevenController,
|
||||
labelText: "Date Field",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTimeField(
|
||||
controller: _textFieldEightController,
|
||||
labelText: "Time Field",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
height: 250,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
|
||||
class MihDateField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String labelText;
|
||||
final bool required;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final double? borderRadius;
|
||||
final double? elevation;
|
||||
final FormFieldValidator<String>? validator;
|
||||
const MihDateField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.labelText,
|
||||
required this.required,
|
||||
this.width,
|
||||
this.height,
|
||||
this.borderRadius,
|
||||
this.elevation,
|
||||
this.validator,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihDateField> createState() => _MihDateFieldState();
|
||||
}
|
||||
|
||||
class _MihDateFieldState extends State<MihDateField> {
|
||||
FormFieldState<String>? _formFieldState;
|
||||
|
||||
Future<void> _selectDate(BuildContext context) async {
|
||||
DateTime? picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: widget.controller.text.isNotEmpty
|
||||
? DateTime.tryParse(widget.controller.text) ?? DateTime.now()
|
||||
: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (picked != null) {
|
||||
widget.controller.text = picked.toString().split(" ")[0];
|
||||
_formFieldState?.didChange(widget.controller.text);
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = MzanziInnovationHub.of(context)!.theme;
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: widget.width,
|
||||
height: widget.height,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.labelText,
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (!widget.required)
|
||||
Text(
|
||||
"(Optional)",
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
FormField<String>(
|
||||
initialValue: widget.controller.text,
|
||||
validator: widget.validator,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
builder: (field) {
|
||||
_formFieldState = field;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Material(
|
||||
elevation: widget.elevation ?? 4.0,
|
||||
borderRadius:
|
||||
BorderRadius.circular(widget.borderRadius ?? 8.0),
|
||||
child: TextFormField(
|
||||
controller: widget.controller,
|
||||
readOnly: true,
|
||||
onTap: () => _selectDate(context),
|
||||
style: TextStyle(
|
||||
color: theme.primaryColor(),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
color: theme.primaryColor(),
|
||||
),
|
||||
errorStyle: const TextStyle(height: 0, fontSize: 0),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 10.0, vertical: 8.0),
|
||||
filled: true,
|
||||
fillColor: theme.secondaryColor(),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: field.hasError
|
||||
? BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 2.0,
|
||||
)
|
||||
: BorderSide.none,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: field.hasError
|
||||
? theme.errorColor()
|
||||
: theme.secondaryColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (value) {
|
||||
field.didChange(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (field.hasError)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
||||
child: Text(
|
||||
field.errorText ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.errorColor(),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MihDropdownField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool requiredText;
|
||||
final List<String> dropdownOptions;
|
||||
final bool editable;
|
||||
final bool enableSearch;
|
||||
final FormFieldValidator<String>? validator;
|
||||
|
||||
const MihDropdownField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.dropdownOptions,
|
||||
required this.requiredText,
|
||||
required this.editable,
|
||||
required this.enableSearch,
|
||||
this.validator,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihDropdownField> createState() => _MihDropdownFieldState();
|
||||
}
|
||||
|
||||
class _MihDropdownFieldState extends State<MihDropdownField> {
|
||||
late List<DropdownMenuEntry<String>> menu;
|
||||
|
||||
List<DropdownMenuEntry<String>> buildMenuOptions(List<String> options) {
|
||||
List<DropdownMenuEntry<String>> menuList = [];
|
||||
final theme = MzanziInnovationHub.of(context)!.theme;
|
||||
for (final i in options) {
|
||||
menuList.add(DropdownMenuEntry(
|
||||
value: i,
|
||||
label: i,
|
||||
style: ButtonStyle(
|
||||
foregroundColor: WidgetStatePropertyAll(theme.primaryColor()),
|
||||
),
|
||||
));
|
||||
}
|
||||
return menuList;
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
menu = buildMenuOptions(widget.dropdownOptions);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
menu = widget.dropdownOptions
|
||||
.map((e) => DropdownMenuEntry(value: e, label: e))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = MzanziInnovationHub.of(context)!.theme;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.hintText,
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (!widget.requiredText)
|
||||
Text(
|
||||
"(Optional)",
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
FormField<String>(
|
||||
validator: widget.validator,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
initialValue: widget.controller.text,
|
||||
builder: (field) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
selectionColor:
|
||||
theme.primaryColor().withValues(alpha: 0.3),
|
||||
selectionHandleColor: theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
child: DropdownMenu(
|
||||
controller: widget.controller,
|
||||
dropdownMenuEntries: menu,
|
||||
enableSearch: widget.enableSearch,
|
||||
enableFilter: widget.enableSearch,
|
||||
enabled: widget.editable,
|
||||
menuHeight: 400,
|
||||
expandedInsets: EdgeInsets.zero,
|
||||
textStyle: TextStyle(
|
||||
color: theme.primaryColor(),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
trailingIcon: Icon(
|
||||
Icons.arrow_drop_down,
|
||||
color: theme.primaryColor(),
|
||||
),
|
||||
selectedTrailingIcon: Icon(
|
||||
Icons.arrow_drop_up,
|
||||
color: theme.primaryColor(),
|
||||
),
|
||||
leadingIcon: IconButton(
|
||||
onPressed: () {
|
||||
widget.controller.clear();
|
||||
field.didChange('');
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.delete_outline_rounded,
|
||||
color: theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
onSelected: (String? selectedValue) {
|
||||
field.didChange(selectedValue);
|
||||
},
|
||||
menuStyle: MenuStyle(
|
||||
backgroundColor:
|
||||
WidgetStatePropertyAll(theme.secondaryColor()),
|
||||
side: WidgetStatePropertyAll(
|
||||
BorderSide(color: theme.primaryColor(), width: 1.0),
|
||||
),
|
||||
shape: WidgetStatePropertyAll(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10), // Increase for more roundness
|
||||
),
|
||||
),
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
errorStyle: const TextStyle(height: 0, fontSize: 0),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 10.0, vertical: 8.0),
|
||||
filled: true,
|
||||
fillColor: theme.secondaryColor(),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide(
|
||||
color: field.hasError
|
||||
? theme.errorColor()
|
||||
: theme.secondaryColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (field.hasError)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
||||
child: Text(
|
||||
field.errorText ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.errorColor(),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
|
||||
class MihNumericStepper extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final Color fillColor;
|
||||
final Color inputColor;
|
||||
final String hintText;
|
||||
final bool requiredText;
|
||||
final double? width;
|
||||
final int? minValue;
|
||||
final int? maxValue;
|
||||
final bool validationOn;
|
||||
const MihNumericStepper({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.fillColor,
|
||||
required this.inputColor,
|
||||
required this.hintText,
|
||||
required this.requiredText,
|
||||
this.width,
|
||||
this.minValue,
|
||||
this.maxValue,
|
||||
required this.validationOn,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihNumericStepper> createState() => _MihNumericStepperState();
|
||||
}
|
||||
|
||||
class _MihNumericStepperState extends State<MihNumericStepper> {
|
||||
late int _currentValue;
|
||||
late bool error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_currentValue =
|
||||
int.tryParse(widget.controller.text) ?? widget.minValue ?? 0;
|
||||
widget.controller.text = _currentValue.toString();
|
||||
print("Current Value: $_currentValue");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
widget.hintText,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: widget.fillColor,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
// color: Colors.white,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
25), // Optional: rounds the corners
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(60, 0, 0,
|
||||
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
||||
spreadRadius: -2,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2.0,
|
||||
left: 5.0,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 40,
|
||||
child: IconButton.filled(
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
WidgetStateProperty.all<Color>(widget.fillColor),
|
||||
),
|
||||
color: widget.inputColor,
|
||||
iconSize: 20,
|
||||
onPressed: () {
|
||||
print("Current Value: $_currentValue");
|
||||
if (_currentValue >= (widget.minValue ?? 0)) {
|
||||
setState(() {
|
||||
widget.controller.text =
|
||||
(_currentValue - 1).toString();
|
||||
_currentValue =
|
||||
int.tryParse(widget.controller.text)!;
|
||||
});
|
||||
}
|
||||
print("New Current Value: $_currentValue");
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.remove,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: _currentValue < (widget.minValue ?? 0) ||
|
||||
(widget.maxValue != null &&
|
||||
_currentValue > widget.maxValue!),
|
||||
child: const SizedBox(
|
||||
height: 21,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
Expanded(
|
||||
child: MihTextFormField(
|
||||
width: widget.width,
|
||||
fillColor: widget.fillColor,
|
||||
inputColor: widget.inputColor,
|
||||
controller: widget.controller,
|
||||
hintText: null,
|
||||
requiredText: widget.requiredText,
|
||||
readOnly: true,
|
||||
numberMode: true,
|
||||
textIputAlignment: TextAlign.center,
|
||||
validator: (value) {
|
||||
if (widget.validationOn) {
|
||||
return MihValidationServices().validateNumber(
|
||||
value, widget.minValue, widget.maxValue);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
// color: Colors.white,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
25), // Optional: rounds the corners
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(60, 0, 0,
|
||||
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
||||
spreadRadius: -2,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2.0,
|
||||
left: 5.0,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 40,
|
||||
child: IconButton.filled(
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
WidgetStateProperty.all<Color>(widget.fillColor),
|
||||
),
|
||||
color: widget.inputColor,
|
||||
iconSize: 20,
|
||||
onPressed: () {
|
||||
print("Current Value: $_currentValue");
|
||||
if (widget.maxValue == null ||
|
||||
_currentValue <= widget.maxValue!) {
|
||||
setState(() {
|
||||
widget.controller.text =
|
||||
(_currentValue + 1).toString();
|
||||
_currentValue =
|
||||
int.tryParse(widget.controller.text)!;
|
||||
});
|
||||
}
|
||||
print("New Current Value: $_currentValue");
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: _currentValue < (widget.minValue ?? 0) ||
|
||||
(widget.maxValue != null &&
|
||||
_currentValue > widget.maxValue!),
|
||||
child: const SizedBox(
|
||||
height: 21,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MihRadioOptions extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final Color fillColor;
|
||||
final Color secondaryFillColor;
|
||||
final bool requiredText;
|
||||
final List<String> radioOptions;
|
||||
const MihRadioOptions({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.fillColor,
|
||||
required this.secondaryFillColor,
|
||||
required this.requiredText,
|
||||
required this.radioOptions,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihRadioOptions> createState() => _MihRadioOptionsState();
|
||||
}
|
||||
|
||||
class _MihRadioOptionsState extends State<MihRadioOptions> {
|
||||
// late String _currentSelection;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.controller.text.isEmpty && widget.radioOptions.isNotEmpty) {
|
||||
widget.controller.text = widget.radioOptions[0];
|
||||
}
|
||||
// else{
|
||||
// int index = widget.radioOptions
|
||||
// .indexWhere((element) => element == option);
|
||||
// _currentSelection = widget.radioOptions[index];
|
||||
// widget.controller.text = option;
|
||||
|
||||
// }
|
||||
// _currentSelection = widget.radioOptions[0];
|
||||
}
|
||||
|
||||
// The method to handle a change in selection.
|
||||
void _onChanged(String? value) {
|
||||
if (value != null) {
|
||||
widget.controller.text = value;
|
||||
}
|
||||
}
|
||||
|
||||
Widget displayRadioOptions(String selection) {
|
||||
return Material(
|
||||
elevation: 4.0,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: widget.fillColor,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Column(
|
||||
children: widget.radioOptions.map((option) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
_onChanged(option);
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
option,
|
||||
style: TextStyle(
|
||||
color: widget.secondaryFillColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
Radio<String>(
|
||||
value: option,
|
||||
groupValue: selection,
|
||||
onChanged: _onChanged,
|
||||
activeColor: widget.secondaryFillColor,
|
||||
fillColor: WidgetStateProperty.resolveWith<Color?>(
|
||||
(Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return widget.secondaryFillColor; // Color when selected
|
||||
}
|
||||
return widget.secondaryFillColor;
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBuilder(
|
||||
animation: widget.controller,
|
||||
builder: (context, child) {
|
||||
final currentSelection = widget.controller.text;
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.hintText,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: widget.fillColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !widget.requiredText,
|
||||
child: Text(
|
||||
"(Optional)",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
color: widget.fillColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
displayRadioOptions(currentSelection),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class MihTextFormField extends StatefulWidget {
|
||||
final Color inputColor;
|
||||
final TextEditingController controller;
|
||||
final bool? hasError;
|
||||
final String hintText;
|
||||
final String? hintText;
|
||||
final double? borderRadius;
|
||||
final bool? multiLineInput;
|
||||
final bool? readOnly;
|
||||
@@ -19,6 +19,7 @@ class MihTextFormField extends StatefulWidget {
|
||||
final FormFieldValidator<String>? validator;
|
||||
final List<String>? autofillHints;
|
||||
final double? elevation;
|
||||
final TextAlign? textIputAlignment;
|
||||
|
||||
const MihTextFormField({
|
||||
Key? key,
|
||||
@@ -38,6 +39,7 @@ class MihTextFormField extends StatefulWidget {
|
||||
this.validator,
|
||||
this.autofillHints,
|
||||
this.elevation,
|
||||
this.textIputAlignment,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -98,31 +100,34 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.hintText,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: widget.fillColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !widget.requiredText,
|
||||
child: Text(
|
||||
"(Optional)",
|
||||
textAlign: TextAlign.right,
|
||||
Visibility(
|
||||
visible: widget.hintText != null,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.hintText ?? "",
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: widget.fillColor,
|
||||
fontSize: 15,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Visibility(
|
||||
visible: !widget.requiredText,
|
||||
child: Text(
|
||||
"(Optional)",
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
color: widget.fillColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
FormField<String>(
|
||||
@@ -141,13 +146,14 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
|
||||
BorderRadius.circular(widget.borderRadius ?? 8.0),
|
||||
child: SizedBox(
|
||||
height: widget.height != null
|
||||
? widget.height! - 25
|
||||
? widget.height! - 30
|
||||
: null,
|
||||
child: TextFormField(
|
||||
controller: widget.controller,
|
||||
cursorColor: widget.inputColor,
|
||||
autofillHints: widget.autofillHints,
|
||||
textAlign: TextAlign.start,
|
||||
textAlign:
|
||||
widget.textIputAlignment ?? TextAlign.start,
|
||||
textAlignVertical: widget.multiLineInput == true
|
||||
? TextAlignVertical.top
|
||||
: TextAlignVertical.center,
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MihTimeField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String labelText;
|
||||
final bool required;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final double? borderRadius;
|
||||
final double? elevation;
|
||||
final FormFieldValidator<String>? validator;
|
||||
|
||||
const MihTimeField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.labelText,
|
||||
required this.required,
|
||||
this.width,
|
||||
this.height,
|
||||
this.borderRadius,
|
||||
this.elevation,
|
||||
this.validator,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihTimeField> createState() => _MihTimeFieldState();
|
||||
}
|
||||
|
||||
class _MihTimeFieldState extends State<MihTimeField> {
|
||||
FormFieldState<String>? _formFieldState;
|
||||
|
||||
Future<void> _selectTime(BuildContext context) async {
|
||||
TimeOfDay? picked = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: widget.controller.text.isNotEmpty
|
||||
? TimeOfDay(
|
||||
hour: int.tryParse(widget.controller.text.split(":")[0]) ?? 0,
|
||||
minute: int.tryParse(widget.controller.text.split(":")[1]) ?? 0,
|
||||
)
|
||||
: TimeOfDay.now(),
|
||||
builder: (context, child) {
|
||||
return MediaQuery(
|
||||
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
|
||||
child: child as Widget,
|
||||
);
|
||||
},
|
||||
);
|
||||
if (picked != null) {
|
||||
final hours = picked.hour.toString().padLeft(2, '0');
|
||||
final minutes = picked.minute.toString().padLeft(2, '0');
|
||||
widget.controller.text = "$hours:$minutes";
|
||||
_formFieldState?.didChange(widget.controller.text);
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = MzanziInnovationHub.of(context)!.theme;
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: widget.width,
|
||||
height: widget.height,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.labelText,
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (!widget.required)
|
||||
Text(
|
||||
"(Optional)",
|
||||
style: TextStyle(
|
||||
color: theme.secondaryColor(),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
FormField<String>(
|
||||
initialValue: widget.controller.text,
|
||||
validator: widget.validator,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
builder: (field) {
|
||||
_formFieldState = field;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Material(
|
||||
elevation: widget.elevation ?? 4.0,
|
||||
borderRadius:
|
||||
BorderRadius.circular(widget.borderRadius ?? 8.0),
|
||||
child: TextFormField(
|
||||
controller: widget.controller,
|
||||
readOnly: true,
|
||||
onTap: () => _selectTime(context),
|
||||
style: TextStyle(
|
||||
color: theme.primaryColor(),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: Icon(
|
||||
Icons.access_time,
|
||||
color: theme.primaryColor(),
|
||||
),
|
||||
errorStyle: const TextStyle(height: 0, fontSize: 0),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 10.0, vertical: 8.0),
|
||||
filled: true,
|
||||
fillColor: theme.secondaryColor(),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: field.hasError
|
||||
? BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 2.0,
|
||||
)
|
||||
: BorderSide.none,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: field.hasError
|
||||
? theme.errorColor()
|
||||
: theme.secondaryColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
widget.borderRadius ?? 8.0),
|
||||
borderSide: BorderSide(
|
||||
color: theme.errorColor(),
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (value) {
|
||||
field.didChange(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (field.hasError)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, top: 4.0),
|
||||
child: Text(
|
||||
field.errorText ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.errorColor(),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MihToggle extends StatefulWidget {
|
||||
final String hintText;
|
||||
final bool initialPostion;
|
||||
final Color fillColor;
|
||||
final Color secondaryFillColor;
|
||||
final bool? readOnly;
|
||||
final void Function(bool) onChange;
|
||||
const MihToggle({
|
||||
super.key,
|
||||
required this.hintText,
|
||||
required this.initialPostion,
|
||||
required this.fillColor,
|
||||
required this.secondaryFillColor,
|
||||
this.readOnly,
|
||||
required this.onChange,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihToggle> createState() => _MihToggleState();
|
||||
}
|
||||
|
||||
class _MihToggleState extends State<MihToggle> {
|
||||
late bool togglePosition;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
setState(() {
|
||||
togglePosition = widget.initialPostion;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.hintText,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: widget.fillColor,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Switch(
|
||||
value: widget.initialPostion,
|
||||
activeColor:
|
||||
widget.readOnly == true ? Colors.grey : widget.secondaryFillColor,
|
||||
activeTrackColor:
|
||||
widget.readOnly == true ? Colors.grey.shade400 : widget.fillColor,
|
||||
inactiveThumbColor:
|
||||
widget.readOnly == true ? Colors.grey : widget.fillColor,
|
||||
inactiveTrackColor: widget.readOnly == true
|
||||
? Colors.grey.shade400
|
||||
: widget.secondaryFillColor,
|
||||
// activeColor: widget.secondaryFillColor,
|
||||
// activeTrackColor: widget.fillColor,
|
||||
// inactiveThumbColor: widget.fillColor,
|
||||
// inactiveTrackColor: widget.secondaryFillColor,
|
||||
onChanged: widget.readOnly != true ? widget.onChange : null,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,13 @@ abstract class AppEnviroment {
|
||||
case Enviroment.dev:
|
||||
{
|
||||
//================= Android Dev Urls =================
|
||||
// baseApiUrl = "http://10.0.2.2:8080";
|
||||
// baseFileUrl = "http://10.0.2.2:9000";
|
||||
// baseAiUrl = "http://10.0.2.2:11434";
|
||||
baseApiUrl = "http://10.0.2.2:8080";
|
||||
baseFileUrl = "http://10.0.2.2:9000";
|
||||
baseAiUrl = "http://10.0.2.2:11434";
|
||||
//================= Web Dev Urls =================
|
||||
baseApiUrl = "http://localhost:8080";
|
||||
baseFileUrl = "http://localhost:9000";
|
||||
baseAiUrl = "http://localhost:11434";
|
||||
// baseApiUrl = "http://localhost:8080";
|
||||
// baseFileUrl = "http://localhost:9000";
|
||||
// baseAiUrl = "http://localhost:11434";
|
||||
break;
|
||||
}
|
||||
case Enviroment.prod:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../main.dart';
|
||||
import '../../../mih_apis/mih_api_calls.dart';
|
||||
import '../../../mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import '../../../mih_components/mih_layout/mih_action.dart';
|
||||
import '../../../mih_components/mih_layout/mih_header.dart';
|
||||
import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
@@ -133,25 +134,30 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
child: MIHDropdownField(
|
||||
child: MihDropdownField(
|
||||
controller: filterController,
|
||||
hintText: "Access Types",
|
||||
hintText: "Access Type",
|
||||
dropdownOptions: const [
|
||||
"All",
|
||||
"Approved",
|
||||
"Pending",
|
||||
"Declined",
|
||||
"Cancelled"
|
||||
"Cancelled",
|
||||
],
|
||||
required: true,
|
||||
requiredText: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 35,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
forceRefresh = true;
|
||||
|
||||
@@ -275,29 +275,6 @@ class _ResetPasswordState extends State<ResetPassword> {
|
||||
},
|
||||
),
|
||||
|
||||
// //email input
|
||||
// SizedBox(
|
||||
// width: 500.0,
|
||||
// child: MIHPassField(
|
||||
// controller: passwordController,
|
||||
// hintText: 'New Password',
|
||||
// required: true,
|
||||
// signIn: false,
|
||||
// ),
|
||||
// ),
|
||||
// //spacer
|
||||
// const SizedBox(height: 10),
|
||||
// //password input
|
||||
// SizedBox(
|
||||
// width: 500.0,
|
||||
// child: MIHPassField(
|
||||
// controller: confirmPasswordController,
|
||||
// hintText: 'Confirm New Password',
|
||||
// required: true,
|
||||
// signIn: false,
|
||||
// ),
|
||||
// ),
|
||||
|
||||
//spacer
|
||||
const SizedBox(height: 25),
|
||||
// sign in button
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_numeric_stepper.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:math_expressions/math_expressions.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
|
||||
class TipCalc extends StatefulWidget {
|
||||
const TipCalc({super.key});
|
||||
@@ -25,6 +26,7 @@ class _TipCalcState extends State<TipCalc> {
|
||||
TextEditingController splitBillController = TextEditingController();
|
||||
TextEditingController noPeopleController = TextEditingController();
|
||||
final ValueNotifier<String> splitValue = ValueNotifier("");
|
||||
late bool splitPosition;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
String tip = "";
|
||||
String total = "";
|
||||
@@ -230,6 +232,8 @@ class _TipCalcState extends State<TipCalc> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
splitBillController.text = "No";
|
||||
noPeopleController.text = "2";
|
||||
splitPosition = false;
|
||||
splitBillController.addListener(splitSelected);
|
||||
}
|
||||
|
||||
@@ -269,13 +273,6 @@ class _TipCalcState extends State<TipCalc> {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
// MIHNumberField(
|
||||
// controller: billAmountController,
|
||||
// hintText: "Bill Amount",
|
||||
// editable: true,
|
||||
// required: true,
|
||||
// enableDecimal: true,
|
||||
// ),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
fillColor:
|
||||
@@ -291,23 +288,40 @@ class _TipCalcState extends State<TipCalc> {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
// MIHNumberField(
|
||||
// controller: tipPercentageController,
|
||||
// hintText: "Tip %",
|
||||
// editable: true,
|
||||
// required: true,
|
||||
// enableDecimal: false,
|
||||
// ),
|
||||
const SizedBox(height: 20),
|
||||
MIHDropdownField(
|
||||
controller: splitBillController,
|
||||
hintText: "Split Bill",
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihToggle(
|
||||
hintText: "Split Bill",
|
||||
initialPostion: splitPosition,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onChange: (value) {
|
||||
setState(() {
|
||||
splitBillController.text = value ? "Yes" : "No";
|
||||
splitPosition = value;
|
||||
if (value) {
|
||||
noPeopleController.text =
|
||||
noPeopleController.text.isEmpty
|
||||
? "2"
|
||||
: noPeopleController.text;
|
||||
} else {
|
||||
noPeopleController.clear();
|
||||
}
|
||||
});
|
||||
// if (value) {
|
||||
// setState(() {
|
||||
// splitBillController.text = "Yes";
|
||||
// splitPosition = value;
|
||||
// });
|
||||
// } else {
|
||||
// setState(() {
|
||||
// splitBillController.text = "No";
|
||||
// splitPosition = value;
|
||||
// });
|
||||
// }
|
||||
},
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: splitValue,
|
||||
builder: (BuildContext context, String value, Widget? child) {
|
||||
@@ -316,33 +330,40 @@ class _TipCalcState extends State<TipCalc> {
|
||||
visible: temp == "Yes",
|
||||
child: Column(
|
||||
children: [
|
||||
MihTextFormField(
|
||||
MihNumericStepper(
|
||||
controller: noPeopleController,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
controller: noPeopleController,
|
||||
multiLineInput: false,
|
||||
hintText: "No. People",
|
||||
requiredText: temp == "Yes",
|
||||
hintText: "No. of People",
|
||||
numberMode: true,
|
||||
validator: (validationValue) {
|
||||
if (temp == "Yes") {
|
||||
return MihValidationServices()
|
||||
.isEmpty(validationValue);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
minValue: 2,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
// MIHNumberField(
|
||||
// MihTextFormField(
|
||||
// fillColor: MzanziInnovationHub.of(context)!
|
||||
// .theme
|
||||
// .secondaryColor(),
|
||||
// inputColor: MzanziInnovationHub.of(context)!
|
||||
// .theme
|
||||
// .primaryColor(),
|
||||
// controller: noPeopleController,
|
||||
// multiLineInput: false,
|
||||
// requiredText: temp == "Yes",
|
||||
// hintText: "No. of People",
|
||||
// editable: true,
|
||||
// required: true,
|
||||
// enableDecimal: false,
|
||||
// numberMode: true,
|
||||
// validator: (validationValue) {
|
||||
// if (temp == "Yes") {
|
||||
// return MihValidationServices()
|
||||
// .isEmpty(validationValue);
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
|
||||
@@ -3,12 +3,12 @@ import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -439,22 +439,22 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHDateField(
|
||||
controller: widget.dateController,
|
||||
lableText: "Date",
|
||||
required: true,
|
||||
),
|
||||
MihDateField(
|
||||
controller: widget.dateController,
|
||||
labelText: "Date",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHTimeField(
|
||||
controller: widget.timeController,
|
||||
lableText: "Time",
|
||||
required: true,
|
||||
),
|
||||
MihTimeField(
|
||||
controller: widget.timeController,
|
||||
labelText: "Time",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
|
||||
@@ -2,15 +2,15 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/appointment.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/business.dart';
|
||||
@@ -140,22 +140,22 @@ class _PatientAccessRequestState extends State<Appointments> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHDateField(
|
||||
controller: _appointmentDateController,
|
||||
lableText: "Date",
|
||||
required: true,
|
||||
),
|
||||
MihDateField(
|
||||
controller: _appointmentDateController,
|
||||
labelText: "Date",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHTimeField(
|
||||
controller: _appointmentTimeController,
|
||||
lableText: "Time",
|
||||
required: true,
|
||||
),
|
||||
MihTimeField(
|
||||
controller: _appointmentTimeController,
|
||||
labelText: "Time",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_numeric_stepper.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_radio_options.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
|
||||
@@ -370,112 +371,116 @@ class _AiChatState extends State<AiChat> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MIHDropdownField(
|
||||
child: MihRadioOptions(
|
||||
controller: _modelController,
|
||||
hintText: "AI Model",
|
||||
dropdownOptions: const [
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
requiredText: true,
|
||||
radioOptions: const [
|
||||
'gemma3:4b',
|
||||
],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 230,
|
||||
child: MIHDropdownField(
|
||||
controller: _ttsVoiceController,
|
||||
hintText: "AI Voice",
|
||||
dropdownOptions: _voicesString,
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
//color: MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
decoration: BoxDecoration(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.successColor(),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(100),
|
||||
),
|
||||
),
|
||||
child: IconButton(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
onPressed: () {
|
||||
print("Start TTS now");
|
||||
|
||||
_speakText(
|
||||
"This is the sample of the Mzansi A.I Voice.");
|
||||
},
|
||||
icon: const Icon(Icons.volume_up),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
IconButton.filled(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_chatFrontSize -= 1;
|
||||
_fontSizeController.text =
|
||||
_chatFrontSize.ceil().toString();
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.remove,
|
||||
SizedBox(
|
||||
width: 230,
|
||||
child: MihDropdownField(
|
||||
controller: _ttsVoiceController,
|
||||
hintText: "AI Voice",
|
||||
dropdownOptions: _voicesString,
|
||||
editable: true,
|
||||
enableSearch: true,
|
||||
requiredText: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
MihTextFormField(
|
||||
width: 200,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
controller: _fontSizeController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
readOnly: true,
|
||||
hintText: "Time",
|
||||
Container(
|
||||
// color: Colors.white,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
25), // Optional: rounds the corners
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(60, 0, 0,
|
||||
0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
||||
spreadRadius: -2,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2.0,
|
||||
left: 5.0,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: IconButton.filled(
|
||||
style: ButtonStyle(
|
||||
backgroundColor:
|
||||
WidgetStateProperty.all<Color>(
|
||||
MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.successColor()),
|
||||
),
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
iconSize: 25,
|
||||
onPressed: () {
|
||||
print("Start TTS now");
|
||||
_speakText(
|
||||
"This is the sample of the Mzansi A.I Voice.");
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.volume_up,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
IconButton.filled(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_chatFrontSize += 1;
|
||||
_fontSizeController.text =
|
||||
_chatFrontSize.ceil().toString();
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MihNumericStepper(
|
||||
controller: _fontSizeController,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
hintText: "Font Size",
|
||||
requiredText: true,
|
||||
minValue: 1,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -537,6 +542,12 @@ class _AiChatState extends State<AiChat> {
|
||||
}
|
||||
}
|
||||
|
||||
void fontSizeChanged() {
|
||||
setState(() {
|
||||
_chatFrontSize = double.parse(_fontSizeController.text);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
@@ -545,12 +556,14 @@ class _AiChatState extends State<AiChat> {
|
||||
_fontSizeController.dispose();
|
||||
_ttsVoiceController.dispose();
|
||||
_ttsVoiceController.removeListener(voiceSelected);
|
||||
_fontSizeController.removeListener(fontSizeChanged);
|
||||
client.endSession();
|
||||
_flutterTts.stop();
|
||||
}
|
||||
|
||||
void initTTS() {
|
||||
_flutterTts.setVolume(0.7);
|
||||
_flutterTts.setVolume(1);
|
||||
_fontSizeController.addListener(fontSizeChanged);
|
||||
// _flutterTts.setSpeechRate(0.6);
|
||||
// _flutterTts.setPitch(1.0);
|
||||
_flutterTts.getVoices.then(
|
||||
@@ -650,27 +663,75 @@ class _AiChatState extends State<AiChat> {
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
left: 15,
|
||||
top: 15,
|
||||
child: Visibility(
|
||||
visible: _showModelOptions.value == true,
|
||||
child: IconButton.filled(
|
||||
iconSize: 20,
|
||||
onPressed: () {
|
||||
if (_showModelOptions.value == true) {
|
||||
setState(() {
|
||||
_showModelOptions.value = false;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_showModelOptions.value = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.settings,
|
||||
child: Container(
|
||||
// color: Colors.white,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(25), // Optional: rounds the corners
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(
|
||||
60, 0, 0, 0), // 0.2 opacity = 51 in alpha (255 * 0.2)
|
||||
spreadRadius: -2,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 5),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 2.0,
|
||||
left: 5.0,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 40,
|
||||
child: IconButton.filled(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all<Color>(
|
||||
MzanziInnovationHub.of(context)!.theme.errorColor()),
|
||||
),
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
iconSize: 20,
|
||||
onPressed: () {
|
||||
if (_showModelOptions.value == true) {
|
||||
setState(() {
|
||||
_showModelOptions.value = false;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_showModelOptions.value = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// IconButton.filled(
|
||||
// iconSize: 20,
|
||||
// onPressed: () {
|
||||
// if (_showModelOptions.value == true) {
|
||||
// setState(() {
|
||||
// _showModelOptions.value = false;
|
||||
// });
|
||||
// } else {
|
||||
// setState(() {
|
||||
// _showModelOptions.value = true;
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.settings,
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
|
||||
@@ -3,8 +3,9 @@ import 'dart:convert';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
@@ -213,22 +214,28 @@ class _BuildEmployeeListState extends State<BuildEmployeeList> {
|
||||
hintText: "Surname",
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: typeController,
|
||||
hintText: "Title",
|
||||
dropdownOptions: const ["Doctor", "Assistant"],
|
||||
required: true,
|
||||
dropdownOptions: const ["Doctor", "Assistant", "Other"],
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: accessController,
|
||||
hintText: "Access",
|
||||
hintText: "Access Type",
|
||||
dropdownOptions: const ["Full", "Partial"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 20.0),
|
||||
Center(
|
||||
|
||||
@@ -2,8 +2,9 @@ import 'dart:convert';
|
||||
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
@@ -168,22 +169,28 @@ class _BuildUserListState extends State<BuildUserList> {
|
||||
hintText: "Email",
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: typeController,
|
||||
hintText: "Title",
|
||||
dropdownOptions: const ["Doctor", "Assistant"],
|
||||
required: true,
|
||||
dropdownOptions: const ["Doctor", "Assistant", "Other"],
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: accessController,
|
||||
hintText: "Access",
|
||||
hintText: "Access Type",
|
||||
dropdownOptions: const ["Full", "Partial"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
Center(
|
||||
|
||||
@@ -6,9 +6,9 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_business_details_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||
@@ -304,13 +304,16 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: typeController,
|
||||
hintText: "Business Type",
|
||||
dropdownOptions: const ["Doctors Office", "Other"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
|
||||
@@ -5,9 +5,9 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||
@@ -252,13 +252,16 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: titleDropdownController,
|
||||
hintText: "Title",
|
||||
dropdownOptions: const ["Doctor", "Assistant", "Other"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
|
||||
@@ -8,12 +8,12 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_location_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
@@ -66,25 +66,6 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
late String env;
|
||||
|
||||
// Future<void> uploadSelectedFile(
|
||||
// PlatformFile file, TextEditingController controller) async {
|
||||
// var token = await supertokens.getaccesstoken();
|
||||
// var request = http2.multipartrequest(
|
||||
// 'post', uri.parse("${appenviroment.baseapiurl}/minio/upload/file/"));
|
||||
// request.headers['accept'] = 'application/json';
|
||||
// request.headers['authorization'] = 'bearer $token';
|
||||
// request.headers['content-type'] = 'multipart/form-data';
|
||||
// request.fields['app_id'] = widget.signedinuser.app_id;
|
||||
// request.fields['folder'] = "business_files";
|
||||
// request.files.add(await http2.multipartfile.frombytes('file', file.bytes!,
|
||||
// filename: file.name.replaceall(regexp(r' '), '-')));
|
||||
// var response1 = await request.send();
|
||||
// if (response1.statuscode == 200) {
|
||||
// } else {
|
||||
// internetconnectionpopup();
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<bool> uploadFile(String id, PlatformFile? selectedFile) async {
|
||||
print("Inside uploud file method");
|
||||
int uploadStatusCode = 0;
|
||||
@@ -113,27 +94,8 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
accessController.text,
|
||||
context,
|
||||
);
|
||||
// var response = await http.post(
|
||||
// Uri.parse("$baseAPI/business-user/insert/"),
|
||||
// headers: <String, String>{
|
||||
// "Content-Type": "application/json; charset=UTF-8"
|
||||
// },
|
||||
// body: jsonEncode(<String, dynamic>{
|
||||
// "business_id": business_id,
|
||||
// "app_id": widget.signedInUser.app_id,
|
||||
// "signature": signtureController.text,
|
||||
// "sig_path":
|
||||
// "${widget.signedInUser.app_id}/business_files/${signtureController.text}",
|
||||
// "title": titleController.text,
|
||||
// "access": accessController.text,
|
||||
// }),
|
||||
// );
|
||||
print("Status code: $statusCode");
|
||||
if (statusCode == 201) {
|
||||
// uploadSelectedFile(selectedSignature, signtureController);
|
||||
// bool successfullyUploadedFile =
|
||||
// await uploadFile(business_id, selectedSignature);
|
||||
// if (successfullyUploadedFile) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).popAndPushNamed(
|
||||
'/',
|
||||
@@ -142,9 +104,6 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
String message =
|
||||
"Your business profile is now live! You can now start connecting with customers and growing your business.";
|
||||
successPopUp(message);
|
||||
// } else {
|
||||
// internetConnectionPopUp();
|
||||
// }
|
||||
} else {
|
||||
internetConnectionPopUp();
|
||||
}
|
||||
@@ -165,35 +124,10 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
logonameController.text,
|
||||
context,
|
||||
);
|
||||
// var response = await http.post(
|
||||
// Uri.parse("$baseAPI/business/insert/"),
|
||||
// headers: <String, String>{
|
||||
// "Content-Type": "application/json; charset=UTF-8"
|
||||
// },
|
||||
// body: jsonEncode(<String, dynamic>{
|
||||
// "Name": nameController.text,
|
||||
// "type": typeController.text,
|
||||
// "registration_no": regController.text,
|
||||
// "logo_name": logonameController.text,
|
||||
// "logo_path":
|
||||
// "${widget.signedInUser.app_id}/business_files/${logonameController.text}",
|
||||
// "contact_no": contactController.text,
|
||||
// "bus_email": emailController.text,
|
||||
// "gps_location": locationController.text,
|
||||
// "practice_no": practiceNoController.text,
|
||||
// "vat_no": vatNoController.text,
|
||||
// }),
|
||||
// );
|
||||
print(response.body);
|
||||
if (response.statusCode == 201) {
|
||||
var businessResponse = jsonDecode(response.body);
|
||||
// bool successfullyUploadedFile =
|
||||
// await uploadFile(widget.signedInUser.app_id, selectedSignature);
|
||||
// if (successfullyUploadedFile) {
|
||||
createBusinessUserAPICall(businessResponse['business_id']);
|
||||
// } else {
|
||||
// internetConnectionPopUp();
|
||||
// }
|
||||
} else {
|
||||
internetConnectionPopUp();
|
||||
}
|
||||
@@ -370,13 +304,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: typeController,
|
||||
hintText: "Business Type",
|
||||
dropdownOptions: const ["Doctors Office", "Other"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
ValueListenableBuilder(
|
||||
@@ -520,13 +457,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
.theme
|
||||
.secondaryColor()),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: titleController,
|
||||
hintText: "Title",
|
||||
dropdownOptions: const ["Doctor", "Assistant"],
|
||||
required: true,
|
||||
dropdownOptions: const ["Doctor", "Assistant", "Other"],
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihTextFormField(
|
||||
@@ -561,13 +501,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: accessController,
|
||||
hintText: "Access",
|
||||
hintText: "Access Type",
|
||||
dropdownOptions: const ["Full", "Partial"],
|
||||
required: true,
|
||||
editable: false,
|
||||
enableSearch: false,
|
||||
editable: true,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
),
|
||||
const SizedBox(height: 20.0),
|
||||
Center(
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_circle_avatar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -332,30 +333,43 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
"Activate Business Account",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Switch(
|
||||
value: businessUser,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
businessUser = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
MihToggle(
|
||||
hintText: "Activate Business Account",
|
||||
initialPostion: businessUser,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onChange: (value) {
|
||||
setState(() {
|
||||
businessUser = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// children: [
|
||||
// const Text(
|
||||
// "Activate Business Account",
|
||||
// style: TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 20,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// width: 10,
|
||||
// ),
|
||||
// Switch(
|
||||
// value: businessUser,
|
||||
// onChanged: (bool value) {
|
||||
// setState(() {
|
||||
// businessUser = value;
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
const SizedBox(height: 30.0),
|
||||
Center(
|
||||
child: MihButton(
|
||||
|
||||
@@ -3,9 +3,9 @@ import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_dropdwn_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
@@ -108,9 +108,15 @@ class _MihCardsState extends State<MihCards> {
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
MIHDropdownField(
|
||||
MihDropdownField(
|
||||
controller: shopController,
|
||||
hintText: "Shop Name",
|
||||
editable: true,
|
||||
enableSearch: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
requiredText: true,
|
||||
dropdownOptions: const [
|
||||
"+More",
|
||||
"Apple Tree",
|
||||
@@ -157,9 +163,6 @@ class _MihCardsState extends State<MihCards> {
|
||||
"Woermann Brock",
|
||||
"Woolworths"
|
||||
],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: shopName,
|
||||
|
||||
@@ -280,7 +280,7 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
|
||||
visible: !hasAccess,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Important Notice: Requesting Patient Profile Access",
|
||||
@@ -343,111 +343,131 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 15.0),
|
||||
Wrap(runSpacing: 10, spacing: 10, children: [
|
||||
Visibility(
|
||||
visible: hasAccess,
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (hasAccess) {
|
||||
Navigator.of(context)
|
||||
.pushNamed('/patient-manager/patient',
|
||||
arguments: PatientViewArguments(
|
||||
widget.signedInUser,
|
||||
widget.patients[index],
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
"business",
|
||||
));
|
||||
} else {
|
||||
noAccessWarning();
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"View Profile",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "No Access",
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
MIHApiCalls.addPatientAccessAPICall(
|
||||
widget.business!.business_id,
|
||||
widget.patients[index].app_id,
|
||||
"patient",
|
||||
widget.business!.Name,
|
||||
widget.personalSelected,
|
||||
BusinessArguments(
|
||||
widget.signedInUser,
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
Center(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
runSpacing: 10,
|
||||
spacing: 10,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: hasAccess,
|
||||
child: Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (hasAccess) {
|
||||
Navigator.of(context)
|
||||
.pushNamed('/patient-manager/patient',
|
||||
arguments: PatientViewArguments(
|
||||
widget.signedInUser,
|
||||
widget.patients[index],
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
"business",
|
||||
));
|
||||
} else {
|
||||
noAccessWarning();
|
||||
}
|
||||
},
|
||||
buttonColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.successColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"View Profile",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
context,
|
||||
);
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Request Access",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "declined",
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
MIHApiCalls.reapplyPatientAccessAPICall(
|
||||
widget.business!.business_id,
|
||||
widget.patients[index].app_id,
|
||||
widget.personalSelected,
|
||||
BusinessArguments(
|
||||
widget.signedInUser,
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "No Access",
|
||||
child: Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
MIHApiCalls.addPatientAccessAPICall(
|
||||
widget.business!.business_id,
|
||||
widget.patients[index].app_id,
|
||||
"patient",
|
||||
widget.business!.Name,
|
||||
widget.personalSelected,
|
||||
BusinessArguments(
|
||||
widget.signedInUser,
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
),
|
||||
context,
|
||||
);
|
||||
},
|
||||
buttonColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.successColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Request Access",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
context,
|
||||
);
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Re-apply",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "declined",
|
||||
child: Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
MIHApiCalls.reapplyPatientAccessAPICall(
|
||||
widget.business!.business_id,
|
||||
widget.patients[index].app_id,
|
||||
widget.personalSelected,
|
||||
BusinessArguments(
|
||||
widget.signedInUser,
|
||||
widget.businessUser,
|
||||
widget.business,
|
||||
),
|
||||
context,
|
||||
);
|
||||
},
|
||||
buttonColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Re-apply",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "pending",
|
||||
child: const SizedBox(
|
||||
width: 500,
|
||||
//height: 50,
|
||||
child: Text(
|
||||
"Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Visibility(
|
||||
visible: !hasAccess && accessStatus == "pending",
|
||||
child: const SizedBox(
|
||||
width: 500,
|
||||
//height: 50,
|
||||
child: Text(
|
||||
"Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."),
|
||||
),
|
||||
),
|
||||
])
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,12 +3,12 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -152,16 +152,22 @@ class _BuildPatientsListState extends State<BuildMyPatientListList> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDateField(
|
||||
MihDateField(
|
||||
controller: dateController,
|
||||
lableText: "Date",
|
||||
labelText: "Date",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTimeField(
|
||||
const SizedBox(height: 10),
|
||||
MihTimeField(
|
||||
controller: timeController,
|
||||
lableText: "Time",
|
||||
labelText: "Time",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 30.0),
|
||||
Center(
|
||||
|
||||
@@ -12,7 +12,6 @@ import 'package:mzansi_innovation_hub/mih_objects/patient_access.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class MihPatientSearch extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
@@ -188,7 +187,6 @@ class _MihPatientSearchState extends State<MihPatientSearch> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
_searchFocusNode.dispose();
|
||||
_mihPatientSearchController.dispose();
|
||||
|
||||
@@ -4,15 +4,15 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_calendar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_time_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_time_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -146,25 +146,6 @@ class _WaitingRoomState extends State<WaitingRoom> {
|
||||
],
|
||||
),
|
||||
),
|
||||
// Positioned(
|
||||
// right: 0,
|
||||
// bottom: 0,
|
||||
// child: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(50),
|
||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// ),
|
||||
// child: IconButton(
|
||||
// color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// onPressed: () {
|
||||
// appointmentTypeSelection();
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.add,
|
||||
// size: 50,
|
||||
// ),
|
||||
// ),
|
||||
// ))
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -340,22 +321,22 @@ class _WaitingRoomState extends State<WaitingRoom> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHDateField(
|
||||
controller: _appointmentDateController,
|
||||
lableText: "Date",
|
||||
required: true,
|
||||
),
|
||||
MihDateField(
|
||||
controller: _appointmentDateController,
|
||||
labelText: "Date",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
// width: 500,
|
||||
child: MIHTimeField(
|
||||
controller: _appointmentTimeController,
|
||||
lableText: "Time",
|
||||
required: true,
|
||||
),
|
||||
MihTimeField(
|
||||
controller: _appointmentTimeController,
|
||||
labelText: "Time",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_claim_statement_generation_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_icd10_code_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_radio_options.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
@@ -93,13 +91,15 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
MIHDropdownField(
|
||||
MihRadioOptions(
|
||||
controller: _docTypeController,
|
||||
hintText: "Document Type",
|
||||
dropdownOptions: const ["Claim", "Statement"],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
requiredText: true,
|
||||
radioOptions: const ["Claim", "Statement"],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Center(
|
||||
@@ -118,23 +118,28 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
const SizedBox(height: 10),
|
||||
MIHDateField(
|
||||
MihDateField(
|
||||
controller: _serviceDateController,
|
||||
lableText: "Date of Service",
|
||||
labelText: "Date of Service",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MIHDropdownField(
|
||||
MihRadioOptions(
|
||||
controller: _serviceDescController,
|
||||
hintText: "Service Decription",
|
||||
dropdownOptions: const [
|
||||
hintText: "Serviced Description",
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
requiredText: true,
|
||||
radioOptions: const [
|
||||
"Consultation",
|
||||
"Procedure",
|
||||
"Other",
|
||||
],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ValueListenableBuilder(
|
||||
@@ -144,29 +149,37 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
switch (value) {
|
||||
case 'Consultation':
|
||||
returnWidget = Column(
|
||||
key: const ValueKey('consultation_fields'), // Added key
|
||||
children: [
|
||||
SizedBox(
|
||||
child: MIHDropdownField(
|
||||
controller: _serviceDescOptionsController,
|
||||
hintText: "Consultation Type",
|
||||
dropdownOptions: const [
|
||||
"General Consultation",
|
||||
"Follow-Up Consultation",
|
||||
"Specialist Consultation",
|
||||
"Emergency Consultation",
|
||||
],
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
MihRadioOptions(
|
||||
key: const ValueKey('consultation_type_dropdown'),
|
||||
controller: _serviceDescOptionsController,
|
||||
hintText: "Consultation Type",
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
requiredText: true,
|
||||
radioOptions: const [
|
||||
"General Consultation",
|
||||
"Follow-Up Consultation",
|
||||
"Specialist Consultation",
|
||||
"Emergency Consultation",
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
);
|
||||
break;
|
||||
case 'Procedure':
|
||||
returnWidget = Column(
|
||||
key: const ValueKey('procedure_fields'), // Added key
|
||||
children: [
|
||||
MihTextFormField(
|
||||
key: const ValueKey(
|
||||
'procedure_name_field'), // Added key
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
@@ -183,6 +196,8 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
key: const ValueKey(
|
||||
'procedure_additional_info_field'), // Added key
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
@@ -192,7 +207,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
controller: _proceedureAdditionalInfoController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
hintText: "Additional Information",
|
||||
hintText: "Additional Procedure Information",
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
@@ -200,10 +215,14 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
break;
|
||||
case 'Other':
|
||||
returnWidget = Column(
|
||||
key: const ValueKey('other_fields'), // Added key
|
||||
children: [
|
||||
MihTextFormField(
|
||||
key: const ValueKey(
|
||||
'other_service_description_field'), // Added key
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
@@ -221,8 +240,10 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
);
|
||||
break;
|
||||
default:
|
||||
returnWidget = const SizedBox();
|
||||
returnWidget = const SizedBox(
|
||||
key: const ValueKey('empty_fields')); // Added key
|
||||
}
|
||||
return returnWidget;
|
||||
},
|
||||
@@ -233,7 +254,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text("ICD-10 Code & Description",
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
@@ -384,16 +405,25 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
}
|
||||
|
||||
void serviceDescriptionSelected() {
|
||||
if (_serviceDescController.text.isNotEmpty) {
|
||||
serviceDesc.value = _serviceDescController.text;
|
||||
String selectedType = _serviceDescController.text;
|
||||
serviceDesc.value = selectedType;
|
||||
if (selectedType == 'Consultation') {
|
||||
_prcedureNameController.clear();
|
||||
_proceedureAdditionalInfoController.clear();
|
||||
} else if (selectedType == 'Procedure') {
|
||||
_serviceDescOptionsController.clear();
|
||||
} else if (selectedType == 'Other') {
|
||||
_prcedureNameController.clear();
|
||||
_proceedureAdditionalInfoController.clear();
|
||||
} else {
|
||||
serviceDesc.value = "";
|
||||
_prcedureNameController.clear();
|
||||
_proceedureAdditionalInfoController.clear();
|
||||
_serviceDescOptionsController.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void hasMedAid() {
|
||||
if (_medAidController.text.isNotEmpty) {
|
||||
medAid.value = _medAidController.text;
|
||||
} else {
|
||||
medAid.value = "";
|
||||
}
|
||||
@@ -403,12 +433,26 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
if (_docTypeController.text.isEmpty ||
|
||||
_serviceDateController.text.isEmpty ||
|
||||
_icd10CodeController.text.isEmpty ||
|
||||
_amountController.text.isEmpty ||
|
||||
_serviceDescOptionsController.text.isEmpty) {
|
||||
_amountController.text.isEmpty) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
switch (_serviceDescController.text) {
|
||||
case 'Consultation':
|
||||
case 'Other':
|
||||
if (_serviceDescOptionsController.text.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'Procedure':
|
||||
if (_prcedureNameController.text.isEmpty ||
|
||||
_proceedureAdditionalInfoController.text.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
String getUserTitle() {
|
||||
@@ -446,12 +490,18 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
_icd10CodeController.dispose();
|
||||
_preauthNoController.dispose();
|
||||
_searchFocusNode.dispose();
|
||||
serviceDesc.dispose();
|
||||
medAid.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_serviceDescController.text = "Consultation";
|
||||
_serviceDescController.addListener(serviceDescriptionSelected);
|
||||
serviceDesc.value = "Consultation";
|
||||
_medAidController.addListener(hasMedAid);
|
||||
_fullNameController.text =
|
||||
"${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}";
|
||||
@@ -466,7 +516,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
|
||||
"${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}";
|
||||
_practiceNoController.text = widget.business!.practice_no;
|
||||
_vatNoController.text = widget.business!.vat_no;
|
||||
super.initState();
|
||||
hasMedAid();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1,10 +1,12 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_numeric_stepper.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/components/medicine_search.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
@@ -16,7 +18,6 @@ import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/perscription.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:supertokens_flutter/http.dart' as http;
|
||||
|
||||
class PrescripInput extends StatefulWidget {
|
||||
@@ -55,6 +56,7 @@ class PrescripInput extends StatefulWidget {
|
||||
class _PrescripInputState extends State<PrescripInput> {
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
final FocusNode _searchFocusNode = FocusNode();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
List<Perscription> perscriptionObjOutput = [];
|
||||
late double width;
|
||||
late double height;
|
||||
@@ -214,12 +216,7 @@ class _PrescripInputState extends State<PrescripInput> {
|
||||
}
|
||||
|
||||
bool isFieldsFilled() {
|
||||
if (widget.medicineController.text.isEmpty ||
|
||||
// widget.quantityController.text.isEmpty ||
|
||||
widget.dosageController.text.isEmpty ||
|
||||
widget.timesDailyController.text.isEmpty ||
|
||||
widget.noDaysController.text.isEmpty ||
|
||||
widget.noRepeatsController.text.isEmpty) {
|
||||
if (widget.medicineController.text.isEmpty) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -351,92 +348,116 @@ class _PrescripInputState extends State<PrescripInput> {
|
||||
Widget displayMedInput() {
|
||||
return Column(
|
||||
children: [
|
||||
//const SizedBox(height: 25.0),
|
||||
|
||||
MihSearchBar(
|
||||
controller: widget.medicineController,
|
||||
hintText: "Search Medicine",
|
||||
prefixIcon: Icons.search,
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onPrefixIconTap: () {
|
||||
getMedsPopUp(widget.medicineController);
|
||||
},
|
||||
onClearIconTap: () {
|
||||
widget.medicineController.clear();
|
||||
},
|
||||
searchFocusNode: _searchFocusNode,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
|
||||
MIHDropdownField(
|
||||
controller: widget.dosageController,
|
||||
hintText: "Dosage",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: widget.timesDailyController,
|
||||
hintText: "Times Daily",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: widget.noDaysController,
|
||||
hintText: "No. Days",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: widget.noRepeatsController,
|
||||
hintText: "No. Repeats",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
editable: true,
|
||||
enableSearch: false,
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MihButton(
|
||||
onPressed: () {
|
||||
if (isFieldsFilled()) {
|
||||
setState(() {
|
||||
updatePerscriptionList();
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
MihSearchBar(
|
||||
controller: widget.medicineController,
|
||||
hintText: "Search Medicine",
|
||||
prefixIcon: Icons.search,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onPrefixIconTap: () {
|
||||
getMedsPopUp(widget.medicineController);
|
||||
},
|
||||
onClearIconTap: () {
|
||||
widget.medicineController.clear();
|
||||
widget.quantityController.clear();
|
||||
widget.dosageController.clear();
|
||||
widget.timesDailyController.clear();
|
||||
widget.noDaysController.clear();
|
||||
widget.noRepeatsController.clear();
|
||||
});
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Input Error");
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Add",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
},
|
||||
searchFocusNode: _searchFocusNode,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihNumericStepper(
|
||||
controller: widget.dosageController,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
hintText: "Dosage",
|
||||
requiredText: true,
|
||||
minValue: 1,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihNumericStepper(
|
||||
controller: widget.timesDailyController,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
hintText: "Times Daily",
|
||||
requiredText: true,
|
||||
minValue: 1,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihNumericStepper(
|
||||
controller: widget.noDaysController,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
hintText: "No. Days",
|
||||
requiredText: true,
|
||||
minValue: 1,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihNumericStepper(
|
||||
controller: widget.noRepeatsController,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
hintText: "No.Repeats",
|
||||
requiredText: true,
|
||||
minValue: 0,
|
||||
// maxValue: 5,
|
||||
validationOn: true,
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
if (isFieldsFilled()) {
|
||||
setState(() {
|
||||
updatePerscriptionList();
|
||||
widget.medicineController.clear();
|
||||
widget.quantityController.text = "1";
|
||||
widget.dosageController.text = "1";
|
||||
widget.timesDailyController.text = "1";
|
||||
widget.noDaysController.text = "1";
|
||||
widget.noRepeatsController.text = "0";
|
||||
});
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(
|
||||
errorType: "Input Error");
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
MihAlertServices().formNotFilledCompletely(context);
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Add",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -543,10 +564,8 @@ class _PrescripInputState extends State<PrescripInput> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var size = MediaQuery.of(context).size;
|
||||
setState(() {
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
});
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
return Wrap(
|
||||
direction: Axis.horizontal,
|
||||
alignment: WrapAlignment.center,
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:mzansi_innovation_hub/mih_objects/business.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/business_user.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/claim_statement_file.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/components/Claim_Statement_Window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/components/claim_statement_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
@@ -2,14 +2,17 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/med_cert_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_file_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_date_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
@@ -60,6 +63,8 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
final noRepeatsController = TextEditingController();
|
||||
final outputController = TextEditingController();
|
||||
late PlatformFile? selected;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final _formKey2 = GlobalKey<FormState>();
|
||||
late String env;
|
||||
|
||||
Future<void> submitDocUploadForm() async {
|
||||
@@ -217,7 +222,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
}
|
||||
}
|
||||
|
||||
void uploudFilePopUp() {
|
||||
void uploudFilePopUp(double width) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
@@ -227,59 +232,103 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
onWindowTapClose: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
windowBody: Column(
|
||||
children: [
|
||||
MIHFileField(
|
||||
controller: selectedFileController,
|
||||
hintText: "Select File",
|
||||
editable: false,
|
||||
required: true,
|
||||
onPressed: () async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['jpg', 'png', 'pdf'],
|
||||
withData: true,
|
||||
);
|
||||
if (result == null) return;
|
||||
final selectedFile = result.files.first;
|
||||
print("Selected file: $selectedFile");
|
||||
setState(() {
|
||||
selected = selectedFile;
|
||||
});
|
||||
setState(() {
|
||||
selectedFileController.text = selectedFile.name;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
MihButton(
|
||||
onPressed: () {
|
||||
if (isFileFieldsFilled()) {
|
||||
submitDocUploadForm();
|
||||
// uploadSelectedFile(selected);
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Input Error");
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Add File",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
windowBody: Padding(
|
||||
padding:
|
||||
MzanziInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.05)
|
||||
: const EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MihTextFormField(
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
controller: selectedFileController,
|
||||
hintText: "Selected File",
|
||||
requiredText: true,
|
||||
readOnly: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
MihButton(
|
||||
onPressed: () async {
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['jpg', 'png', 'pdf'],
|
||||
withData: true,
|
||||
);
|
||||
if (result == null) return;
|
||||
final selectedFile = result.files.first;
|
||||
print("Selected file: $selectedFile");
|
||||
setState(() {
|
||||
selected = selectedFile;
|
||||
});
|
||||
setState(() {
|
||||
selectedFileController.text = selectedFile.name;
|
||||
});
|
||||
},
|
||||
buttonColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
child: Text(
|
||||
"Attach",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
submitDocUploadForm();
|
||||
// uploadSelectedFile(selected);
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
MihAlertServices().formNotFilledCompletely(context);
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Add File",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -297,37 +346,67 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
},
|
||||
windowBody: Column(
|
||||
children: [
|
||||
Medcertinput(
|
||||
startDateController: startDateController,
|
||||
endDateTextController: endDateTextController,
|
||||
retDateTextController: retDateTextController,
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
MihButton(
|
||||
onPressed: () async {
|
||||
if (isMedCertFieldsFilled()) {
|
||||
await generateMedCert();
|
||||
//Navigator.pop(context);
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Input Error");
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Generate",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
MihForm(
|
||||
formKey: _formKey2,
|
||||
formFields: [
|
||||
MihDateField(
|
||||
controller: startDateController,
|
||||
labelText: "From",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihDateField(
|
||||
controller: endDateTextController,
|
||||
labelText: "Up to Including",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihDateField(
|
||||
controller: retDateTextController,
|
||||
labelText: "Return",
|
||||
required: true,
|
||||
validator: (value) {
|
||||
return MihValidationServices().isEmpty(value);
|
||||
},
|
||||
),
|
||||
// Medcertinput(
|
||||
// startDateController: startDateController,
|
||||
// endDateTextController: endDateTextController,
|
||||
// retDateTextController: retDateTextController,
|
||||
// ),
|
||||
const SizedBox(height: 15.0),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () async {
|
||||
if (_formKey2.currentState!.validate()) {
|
||||
await generateMedCert();
|
||||
//Navigator.pop(context);
|
||||
} else {
|
||||
MihAlertServices().formNotFilledCompletely(context);
|
||||
}
|
||||
},
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Generate",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -344,11 +423,11 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
windowTitle: "Create Prescription",
|
||||
onWindowTapClose: () {
|
||||
medicineController.clear();
|
||||
quantityController.clear();
|
||||
dosageController.clear();
|
||||
timesDailyController.clear();
|
||||
noDaysController.clear();
|
||||
noRepeatsController.clear();
|
||||
quantityController.text = "1";
|
||||
dosageController.text = "1";
|
||||
timesDailyController.text = "1";
|
||||
noDaysController.text = "1";
|
||||
noRepeatsController.text = "0";
|
||||
Navigator.pop(context);
|
||||
},
|
||||
windowBody: Column(
|
||||
@@ -391,7 +470,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
}
|
||||
}
|
||||
|
||||
Widget getMenu() {
|
||||
Widget getMenu(double width) {
|
||||
if (widget.type == "personal") {
|
||||
return Positioned(
|
||||
right: 10,
|
||||
@@ -415,7 +494,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
backgroundColor:
|
||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
onTap: () {
|
||||
uploudFilePopUp();
|
||||
uploudFilePopUp(width);
|
||||
},
|
||||
)
|
||||
],
|
||||
@@ -444,7 +523,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
backgroundColor:
|
||||
MzanziInnovationHub.of(context)!.theme.successColor(),
|
||||
onTap: () {
|
||||
uploudFilePopUp();
|
||||
uploudFilePopUp(width);
|
||||
},
|
||||
),
|
||||
SpeedDialChild(
|
||||
@@ -489,70 +568,6 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> setIcons() {
|
||||
if (widget.type == "personal") {
|
||||
return [
|
||||
Text(
|
||||
"Documents",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
uploudFilePopUp();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
)
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
Text(
|
||||
"Documents",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
medCertPopUp();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.sick_outlined,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
prescritionPopUp();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.medication_outlined,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
uploudFilePopUp();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
void successPopUp(String message) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -603,13 +618,14 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double screenWidth = MediaQuery.of(context).size.width;
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
bodyItem: getBody(),
|
||||
bodyItem: getBody(screenWidth),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBody() {
|
||||
Widget getBody(double width) {
|
||||
return Stack(
|
||||
children: [
|
||||
MihSingleChildScroll(
|
||||
@@ -641,7 +657,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
|
||||
},
|
||||
),
|
||||
),
|
||||
getMenu(),
|
||||
getMenu(width),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
|
||||
@@ -39,8 +40,9 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
final medMainMemController = TextEditingController();
|
||||
final medAidCodeController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
double textFieldWidth = 500;
|
||||
double textFieldWidth = 300;
|
||||
late String medAid;
|
||||
late bool medAidPosition;
|
||||
|
||||
Widget getPatientDetailsField() {
|
||||
return Center(
|
||||
@@ -146,16 +148,37 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
medAidDet.add(
|
||||
SizedBox(
|
||||
width: textFieldWidth,
|
||||
child: MihTextFormField(
|
||||
// width: textFieldWidth,
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
controller: medAidController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
readOnly: true,
|
||||
child: MihToggle(
|
||||
hintText: "Medical Aid",
|
||||
initialPostion: medAidPosition,
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
readOnly: true,
|
||||
onChange: (value) {
|
||||
if (value) {
|
||||
setState(() {
|
||||
medAidController.text = "Yes";
|
||||
medAidPosition = value;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medAidController.text = "No";
|
||||
medAidPosition = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
// MihTextFormField(
|
||||
// // width: textFieldWidth,
|
||||
// fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// controller: medAidController,
|
||||
// multiLineInput: false,
|
||||
// requiredText: true,
|
||||
// readOnly: true,
|
||||
// hintText: "Medical Aid",
|
||||
// ),
|
||||
),
|
||||
);
|
||||
bool req;
|
||||
@@ -216,6 +239,7 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
Visibility(
|
||||
visible: req,
|
||||
child: SizedBox(
|
||||
width: textFieldWidth,
|
||||
child: MihTextFormField(
|
||||
// width: textFieldWidth,
|
||||
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
@@ -299,6 +323,11 @@ class _PatientInfoState extends State<PatientInfo> {
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid_code);
|
||||
medAid = widget.selectedPatient.medical_aid;
|
||||
});
|
||||
if (medAid == "Yes") {
|
||||
medAidPosition = true;
|
||||
} else {
|
||||
medAidPosition = false;
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'dart:convert';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart';
|
||||
@@ -11,6 +10,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_build
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -46,6 +46,8 @@ class _AddPatientState extends State<AddPatient> {
|
||||
final medMainMemController = TextEditingController();
|
||||
final medAidCodeController = TextEditingController();
|
||||
|
||||
late bool medAidPosition;
|
||||
late bool medMainMemberPosition;
|
||||
final baseAPI = AppEnviroment.baseApiUrl;
|
||||
late int futureDocOfficeId;
|
||||
//late bool medRequired;
|
||||
@@ -297,13 +299,26 @@ class _AddPatientState extends State<AddPatient> {
|
||||
.theme
|
||||
.secondaryColor()),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medAidController,
|
||||
MihToggle(
|
||||
hintText: "Medical Aid",
|
||||
editable: true,
|
||||
required: true,
|
||||
enableSearch: false,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
initialPostion: medAidPosition,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onChange: (value) {
|
||||
if (value) {
|
||||
setState(() {
|
||||
medAidController.text = "Yes";
|
||||
medAidPosition = value;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medAidController.text = "No";
|
||||
medAidPosition = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: medRequired,
|
||||
@@ -313,13 +328,28 @@ class _AddPatientState extends State<AddPatient> {
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
MihToggle(
|
||||
hintText: "Main Member",
|
||||
editable: value,
|
||||
required: value,
|
||||
enableSearch: false,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
initialPostion: medMainMemberPosition,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
onChange: (value) {
|
||||
if (value) {
|
||||
setState(() {
|
||||
medMainMemController.text = "Yes";
|
||||
medMainMemberPosition = value;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medMainMemController.text = "No";
|
||||
medMainMemberPosition = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihTextFormField(
|
||||
@@ -520,7 +550,10 @@ class _AddPatientState extends State<AddPatient> {
|
||||
fnameController.text = widget.signedInUser.fname;
|
||||
lnameController.text = widget.signedInUser.lname;
|
||||
emailController.text = widget.signedInUser.email;
|
||||
medAidPosition = false;
|
||||
medMainMemberPosition = false;
|
||||
medAidController.text = "No";
|
||||
medMainMemController.text = "No";
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'dart:convert';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_action.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_header.dart';
|
||||
@@ -11,6 +10,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_build
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_toggle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_env/env.dart';
|
||||
@@ -54,6 +54,8 @@ class _EditPatientState extends State<EditPatient> {
|
||||
final apiUrlDelete = "${AppEnviroment.baseApiUrl}/patients/delete/";
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
late bool medAidPosition;
|
||||
late bool medMainMemberPosition;
|
||||
late int futureDocOfficeId;
|
||||
late String userEmail;
|
||||
// bool medRequired = false;
|
||||
@@ -511,13 +513,26 @@ class _EditPatientState extends State<EditPatient> {
|
||||
.theme
|
||||
.secondaryColor()),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medAidController,
|
||||
MihToggle(
|
||||
hintText: "Medical Aid",
|
||||
editable: true,
|
||||
required: true,
|
||||
enableSearch: false,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
initialPostion: medAidPosition,
|
||||
fillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
secondaryFillColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
onChange: (value) {
|
||||
if (value) {
|
||||
setState(() {
|
||||
medAidController.text = "Yes";
|
||||
medAidPosition = value;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medAidController.text = "No";
|
||||
medAidPosition = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: medRequired,
|
||||
@@ -527,13 +542,28 @@ class _EditPatientState extends State<EditPatient> {
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
MihToggle(
|
||||
hintText: "Main Member",
|
||||
editable: value,
|
||||
required: value,
|
||||
enableSearch: false,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
initialPostion: medMainMemberPosition,
|
||||
fillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
secondaryFillColor: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
onChange: (value) {
|
||||
if (value) {
|
||||
setState(() {
|
||||
medMainMemController.text = "Yes";
|
||||
medMainMemberPosition = value;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medMainMemController.text = "No";
|
||||
medMainMemberPosition = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MihTextFormField(
|
||||
@@ -747,6 +777,18 @@ class _EditPatientState extends State<EditPatient> {
|
||||
medAidCodeController.text = widget.selectedPatient.medical_aid_code;
|
||||
});
|
||||
|
||||
if (medAidController.text == "Yes") {
|
||||
medAidPosition = true;
|
||||
} else {
|
||||
medAidPosition = false;
|
||||
medAidController.text = "No";
|
||||
}
|
||||
if (medMainMemController.text == "Yes") {
|
||||
medMainMemberPosition = true;
|
||||
} else {
|
||||
medMainMemberPosition = false;
|
||||
medMainMemController.text = "No";
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user