Merge pull request #198 from yaso-meth/NEW--UX-Option-Selection

NEW--UX-Option-Selection
This commit is contained in:
yaso-meth
2025-06-10 16:49:51 +02:00
committed by GitHub
43 changed files with 2207 additions and 2359 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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