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"; 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? validatePassword(String? password) {
String? errorMessage = ""; String? errorMessage = "";
if (password == null || password.isEmpty) { 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_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_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_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_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_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_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_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_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_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_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_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_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 { class PackageToolOne extends StatefulWidget {
const PackageToolOne({super.key}); const PackageToolOne({super.key});
@@ -35,6 +41,12 @@ class _PackageToolOneState extends State<PackageToolOne> {
TextEditingController _textFieldTwoController = TextEditingController(); TextEditingController _textFieldTwoController = TextEditingController();
TextEditingController _textFieldThreeController = TextEditingController(); TextEditingController _textFieldThreeController = TextEditingController();
TextEditingController _textFieldFourController = 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 FocusNode searchFocusNode = FocusNode();
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
@@ -220,6 +232,83 @@ class _PackageToolOneState extends State<PackageToolOne> {
: null, : null,
), ),
const SizedBox(height: 10), 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( MihTextFormField(
height: 250, height: 250,
fillColor: MzanziInnovationHub.of(context)! 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 Color inputColor;
final TextEditingController controller; final TextEditingController controller;
final bool? hasError; final bool? hasError;
final String hintText; final String? hintText;
final double? borderRadius; final double? borderRadius;
final bool? multiLineInput; final bool? multiLineInput;
final bool? readOnly; final bool? readOnly;
@@ -19,6 +19,7 @@ class MihTextFormField extends StatefulWidget {
final FormFieldValidator<String>? validator; final FormFieldValidator<String>? validator;
final List<String>? autofillHints; final List<String>? autofillHints;
final double? elevation; final double? elevation;
final TextAlign? textIputAlignment;
const MihTextFormField({ const MihTextFormField({
Key? key, Key? key,
@@ -38,6 +39,7 @@ class MihTextFormField extends StatefulWidget {
this.validator, this.validator,
this.autofillHints, this.autofillHints,
this.elevation, this.elevation,
this.textIputAlignment,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -98,15 +100,17 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Visibility(
visible: widget.hintText != null,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
widget.hintText, widget.hintText ?? "",
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: TextStyle( style: TextStyle(
color: widget.fillColor, color: widget.fillColor,
fontSize: 15, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -124,6 +128,7 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
), ),
], ],
), ),
),
const SizedBox(height: 4), const SizedBox(height: 4),
FormField<String>( FormField<String>(
initialValue: widget.controller.text, initialValue: widget.controller.text,
@@ -141,13 +146,14 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
BorderRadius.circular(widget.borderRadius ?? 8.0), BorderRadius.circular(widget.borderRadius ?? 8.0),
child: SizedBox( child: SizedBox(
height: widget.height != null height: widget.height != null
? widget.height! - 25 ? widget.height! - 30
: null, : null,
child: TextFormField( child: TextFormField(
controller: widget.controller, controller: widget.controller,
cursorColor: widget.inputColor, cursorColor: widget.inputColor,
autofillHints: widget.autofillHints, autofillHints: widget.autofillHints,
textAlign: TextAlign.start, textAlign:
widget.textIputAlignment ?? TextAlign.start,
textAlignVertical: widget.multiLineInput == true textAlignVertical: widget.multiLineInput == true
? TextAlignVertical.top ? TextAlignVertical.top
: TextAlignVertical.center, : 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: case Enviroment.dev:
{ {
//================= Android Dev Urls ================= //================= Android Dev Urls =================
// baseApiUrl = "http://10.0.2.2:8080"; baseApiUrl = "http://10.0.2.2:8080";
// baseFileUrl = "http://10.0.2.2:9000"; baseFileUrl = "http://10.0.2.2:9000";
// baseAiUrl = "http://10.0.2.2:11434"; baseAiUrl = "http://10.0.2.2:11434";
//================= Web Dev Urls ================= //================= Web Dev Urls =================
baseApiUrl = "http://localhost:8080"; // baseApiUrl = "http://localhost:8080";
baseFileUrl = "http://localhost:9000"; // baseFileUrl = "http://localhost:9000";
baseAiUrl = "http://localhost:11434"; // baseAiUrl = "http://localhost:11434";
break; break;
} }
case Enviroment.prod: 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_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_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../main.dart'; import '../../../main.dart';
import '../../../mih_apis/mih_api_calls.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_action.dart';
import '../../../mih_components/mih_layout/mih_header.dart'; import '../../../mih_components/mih_layout/mih_header.dart';
import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import '../../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
@@ -133,25 +134,30 @@ class _MihAccessRequestState extends State<MihAccessRequest> {
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Flexible( Flexible(
child: MIHDropdownField( child: MihDropdownField(
controller: filterController, controller: filterController,
hintText: "Access Types", hintText: "Access Type",
dropdownOptions: const [ dropdownOptions: const [
"All", "All",
"Approved", "Approved",
"Pending", "Pending",
"Declined", "Declined",
"Cancelled" "Cancelled",
], ],
required: true, requiredText: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
), ),
IconButton( IconButton(
iconSize: 35,
onPressed: () { onPressed: () {
setState(() { setState(() {
forceRefresh = true; 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 //spacer
const SizedBox(height: 25), const SizedBox(height: 25),
// sign in button // sign in button

View File

@@ -1,16 +1,17 @@
import 'package:mzansi_innovation_hub/main.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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_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_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_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_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_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_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_text_form_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:math_expressions/math_expressions.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 { class TipCalc extends StatefulWidget {
const TipCalc({super.key}); const TipCalc({super.key});
@@ -25,6 +26,7 @@ class _TipCalcState extends State<TipCalc> {
TextEditingController splitBillController = TextEditingController(); TextEditingController splitBillController = TextEditingController();
TextEditingController noPeopleController = TextEditingController(); TextEditingController noPeopleController = TextEditingController();
final ValueNotifier<String> splitValue = ValueNotifier(""); final ValueNotifier<String> splitValue = ValueNotifier("");
late bool splitPosition;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
String tip = ""; String tip = "";
String total = ""; String total = "";
@@ -230,6 +232,8 @@ class _TipCalcState extends State<TipCalc> {
void initState() { void initState() {
super.initState(); super.initState();
splitBillController.text = "No"; splitBillController.text = "No";
noPeopleController.text = "2";
splitPosition = false;
splitBillController.addListener(splitSelected); splitBillController.addListener(splitSelected);
} }
@@ -269,13 +273,6 @@ class _TipCalcState extends State<TipCalc> {
return MihValidationServices().isEmpty(value); return MihValidationServices().isEmpty(value);
}, },
), ),
// MIHNumberField(
// controller: billAmountController,
// hintText: "Bill Amount",
// editable: true,
// required: true,
// enableDecimal: true,
// ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( MihTextFormField(
fillColor: fillColor:
@@ -291,23 +288,40 @@ class _TipCalcState extends State<TipCalc> {
return MihValidationServices().isEmpty(value); 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), 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( ValueListenableBuilder(
valueListenable: splitValue, valueListenable: splitValue,
builder: (BuildContext context, String value, Widget? child) { builder: (BuildContext context, String value, Widget? child) {
@@ -316,33 +330,40 @@ class _TipCalcState extends State<TipCalc> {
visible: temp == "Yes", visible: temp == "Yes",
child: Column( child: Column(
children: [ children: [
MihTextFormField( MihNumericStepper(
controller: noPeopleController,
fillColor: MzanziInnovationHub.of(context)! fillColor: MzanziInnovationHub.of(context)!
.theme .theme
.secondaryColor(), .secondaryColor(),
inputColor: MzanziInnovationHub.of(context)! inputColor: MzanziInnovationHub.of(context)!
.theme .theme
.primaryColor(), .primaryColor(),
controller: noPeopleController, hintText: "No. People",
multiLineInput: false,
requiredText: temp == "Yes", requiredText: temp == "Yes",
hintText: "No. of People", minValue: 2,
numberMode: true, // maxValue: 5,
validator: (validationValue) { validationOn: true,
if (temp == "Yes") {
return MihValidationServices()
.isEmpty(validationValue);
} else {
return null;
}
},
), ),
// MIHNumberField( // MihTextFormField(
// fillColor: MzanziInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// inputColor: MzanziInnovationHub.of(context)!
// .theme
// .primaryColor(),
// controller: noPeopleController, // controller: noPeopleController,
// multiLineInput: false,
// requiredText: temp == "Yes",
// hintText: "No. of People", // hintText: "No. of People",
// editable: true, // numberMode: true,
// required: true, // validator: (validationValue) {
// enableDecimal: false, // if (temp == "Yes") {
// return MihValidationServices()
// .isEmpty(validationValue);
// } else {
// return null;
// }
// },
// ), // ),
const SizedBox(height: 10), 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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.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_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_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_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_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_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_delete_message.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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_env/env.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart';
@@ -439,22 +439,22 @@ class _BuildAppointmentListState extends State<BuildAppointmentList> {
}, },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihDateField(
// width: 500,
child: MIHDateField(
controller: widget.dateController, controller: widget.dateController,
lableText: "Date", labelText: "Date",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500,
child: MIHTimeField(
controller: widget.timeController, controller: widget.timeController,
lableText: "Time", labelText: "Time",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( 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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.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_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_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_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_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_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_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_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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_objects/appointment.dart'; import 'package:mzansi_innovation_hub/mih_objects/appointment.dart';
import 'package:mzansi_innovation_hub/mih_objects/business.dart'; import 'package:mzansi_innovation_hub/mih_objects/business.dart';
@@ -140,22 +140,22 @@ class _PatientAccessRequestState extends State<Appointments> {
}, },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihDateField(
// width: 500,
child: MIHDateField(
controller: _appointmentDateController, controller: _appointmentDateController,
lableText: "Date", labelText: "Date",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500,
child: MIHTimeField(
controller: _appointmentTimeController, controller: _appointmentTimeController,
lableText: "Time", labelText: "Time",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( MihTextFormField(

View File

@@ -1,13 +1,14 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:mzansi_innovation_hub/main.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_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_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_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_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_env/env.dart'; import 'package:mzansi_innovation_hub/mih_env/env.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.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( Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
SizedBox( SizedBox(
width: 300, width: 300,
child: MIHDropdownField( child: MihRadioOptions(
controller: _modelController, controller: _modelController,
hintText: "AI Model", hintText: "AI Model",
dropdownOptions: const [ fillColor: MzanziInnovationHub.of(context)!
'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 .theme
.successColor(), .secondaryColor(),
borderRadius: const BorderRadius.all( secondaryFillColor:
Radius.circular(100), MzanziInnovationHub.of(context)!
),
),
child: IconButton(
color: MzanziInnovationHub.of(context)!
.theme .theme
.primaryColor(), .primaryColor(),
onPressed: () { requiredText: true,
print("Start TTS now"); radioOptions: const [
'gemma3:4b',
_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( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
IconButton.filled( SizedBox(
onPressed: () { width: 230,
setState(() { child: MihDropdownField(
_chatFrontSize -= 1; controller: _ttsVoiceController,
_fontSizeController.text = hintText: "AI Voice",
_chatFrontSize.ceil().toString(); dropdownOptions: _voicesString,
}); editable: true,
enableSearch: true,
requiredText: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
}, },
icon: const Icon(
Icons.remove,
), ),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
MihTextFormField( Container(
width: 200, // 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(height: 10),
Row(
children: [
SizedBox(
width: 300,
child: MihNumericStepper(
controller: _fontSizeController,
fillColor: MzanziInnovationHub.of(context)! fillColor: MzanziInnovationHub.of(context)!
.theme .theme
.secondaryColor(), .secondaryColor(),
inputColor: MzanziInnovationHub.of(context)! inputColor: MzanziInnovationHub.of(context)!
.theme .theme
.primaryColor(), .primaryColor(),
controller: _fontSizeController, hintText: "Font Size",
multiLineInput: false,
requiredText: true, requiredText: true,
readOnly: true, minValue: 1,
hintText: "Time", // maxValue: 5,
), validationOn: true,
const SizedBox(width: 10),
IconButton.filled(
onPressed: () {
setState(() {
_chatFrontSize += 1;
_fontSizeController.text =
_chatFrontSize.ceil().toString();
});
},
icon: const Icon(
Icons.add,
), ),
), ),
], ],
@@ -537,6 +542,12 @@ class _AiChatState extends State<AiChat> {
} }
} }
void fontSizeChanged() {
setState(() {
_chatFrontSize = double.parse(_fontSizeController.text);
});
}
@override @override
void dispose() { void dispose() {
// TODO: implement dispose // TODO: implement dispose
@@ -545,12 +556,14 @@ class _AiChatState extends State<AiChat> {
_fontSizeController.dispose(); _fontSizeController.dispose();
_ttsVoiceController.dispose(); _ttsVoiceController.dispose();
_ttsVoiceController.removeListener(voiceSelected); _ttsVoiceController.removeListener(voiceSelected);
_fontSizeController.removeListener(fontSizeChanged);
client.endSession(); client.endSession();
_flutterTts.stop(); _flutterTts.stop();
} }
void initTTS() { void initTTS() {
_flutterTts.setVolume(0.7); _flutterTts.setVolume(1);
_fontSizeController.addListener(fontSizeChanged);
// _flutterTts.setSpeechRate(0.6); // _flutterTts.setSpeechRate(0.6);
// _flutterTts.setPitch(1.0); // _flutterTts.setPitch(1.0);
_flutterTts.getVoices.then( _flutterTts.getVoices.then(
@@ -650,11 +663,39 @@ class _AiChatState extends State<AiChat> {
], ],
), ),
Positioned( Positioned(
left: 0, left: 15,
top: 0, top: 15,
child: Visibility( child: Visibility(
visible: _showModelOptions.value == true, visible: _showModelOptions.value == true,
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( child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MzanziInnovationHub.of(context)!.theme.errorColor()),
),
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
iconSize: 20, iconSize: 20,
onPressed: () { onPressed: () {
if (_showModelOptions.value == true) { if (_showModelOptions.value == true) {
@@ -668,11 +709,31 @@ class _AiChatState extends State<AiChat> {
} }
}, },
icon: const Icon( icon: const Icon(
Icons.settings, 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( Positioned(
right: 10, right: 10,
bottom: 80, bottom: 80,

View File

@@ -3,8 +3,9 @@ import 'dart:convert';
import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:mzansi_innovation_hub/main.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_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_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_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_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_text_form_field.dart';
@@ -213,22 +214,28 @@ class _BuildEmployeeListState extends State<BuildEmployeeList> {
hintText: "Surname", hintText: "Surname",
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
MIHDropdownField( MihDropdownField(
controller: typeController, controller: typeController,
hintText: "Title", hintText: "Title",
dropdownOptions: const ["Doctor", "Assistant"], dropdownOptions: const ["Doctor", "Assistant", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihDropdownField(
controller: accessController, controller: accessController,
hintText: "Access", hintText: "Access Type",
dropdownOptions: const ["Full", "Partial"], dropdownOptions: const ["Full", "Partial"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
Center( Center(

View File

@@ -2,8 +2,9 @@ import 'dart:convert';
import 'package:mzansi_innovation_hub/main.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_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_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_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_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_text_form_field.dart';
@@ -168,22 +169,28 @@ class _BuildUserListState extends State<BuildUserList> {
hintText: "Email", hintText: "Email",
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
MIHDropdownField( MihDropdownField(
controller: typeController, controller: typeController,
hintText: "Title", hintText: "Title",
dropdownOptions: const ["Doctor", "Assistant"], dropdownOptions: const ["Doctor", "Assistant", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihDropdownField(
controller: accessController, controller: accessController,
hintText: "Access", hintText: "Access Type",
dropdownOptions: const ["Full", "Partial"], dropdownOptions: const ["Full", "Partial"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
Center( 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_file_api.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_location_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_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_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_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_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_tool_body.dart';
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_package_alert.dart';
@@ -304,13 +304,16 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
}, },
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
MIHDropdownField( MihDropdownField(
controller: typeController, controller: typeController,
hintText: "Business Type", hintText: "Business Type",
dropdownOptions: const ["Doctors Office", "Other"], dropdownOptions: const ["Doctors Office", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( 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_file_api.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.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_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_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_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_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_tool_body.dart';
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_package_alert.dart';
@@ -252,13 +252,16 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
), ),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
MIHDropdownField( MihDropdownField(
controller: titleDropdownController, controller: titleDropdownController,
hintText: "Title", hintText: "Title",
dropdownOptions: const ["Doctor", "Assistant", "Other"], dropdownOptions: const ["Doctor", "Assistant", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( 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_location_api.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_my_business_user_apis.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_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_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.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_header.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_layout_builder.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_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_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_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_error_message.dart';
@@ -66,25 +66,6 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
late String env; 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 { Future<bool> uploadFile(String id, PlatformFile? selectedFile) async {
print("Inside uploud file method"); print("Inside uploud file method");
int uploadStatusCode = 0; int uploadStatusCode = 0;
@@ -113,27 +94,8 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
accessController.text, accessController.text,
context, 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"); print("Status code: $statusCode");
if (statusCode == 201) { if (statusCode == 201) {
// uploadSelectedFile(selectedSignature, signtureController);
// bool successfullyUploadedFile =
// await uploadFile(business_id, selectedSignature);
// if (successfullyUploadedFile) {
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
@@ -142,9 +104,6 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
String message = String message =
"Your business profile is now live! You can now start connecting with customers and growing your business."; "Your business profile is now live! You can now start connecting with customers and growing your business.";
successPopUp(message); successPopUp(message);
// } else {
// internetConnectionPopUp();
// }
} else { } else {
internetConnectionPopUp(); internetConnectionPopUp();
} }
@@ -165,35 +124,10 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
logonameController.text, logonameController.text,
context, 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); print(response.body);
if (response.statusCode == 201) { if (response.statusCode == 201) {
var businessResponse = jsonDecode(response.body); var businessResponse = jsonDecode(response.body);
// bool successfullyUploadedFile =
// await uploadFile(widget.signedInUser.app_id, selectedSignature);
// if (successfullyUploadedFile) {
createBusinessUserAPICall(businessResponse['business_id']); createBusinessUserAPICall(businessResponse['business_id']);
// } else {
// internetConnectionPopUp();
// }
} else { } else {
internetConnectionPopUp(); internetConnectionPopUp();
} }
@@ -370,13 +304,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
}, },
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
MIHDropdownField( MihDropdownField(
controller: typeController, controller: typeController,
hintText: "Business Type", hintText: "Business Type",
dropdownOptions: const ["Doctors Office", "Other"], dropdownOptions: const ["Doctors Office", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
ValueListenableBuilder( ValueListenableBuilder(
@@ -520,13 +457,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
.theme .theme
.secondaryColor()), .secondaryColor()),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihDropdownField(
controller: titleController, controller: titleController,
hintText: "Title", hintText: "Title",
dropdownOptions: const ["Doctor", "Assistant"], dropdownOptions: const ["Doctor", "Assistant", "Other"],
required: true,
editable: true, editable: true,
enableSearch: false, enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MihTextFormField( MihTextFormField(
@@ -561,13 +501,16 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
}, },
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
MIHDropdownField( MihDropdownField(
controller: accessController, controller: accessController,
hintText: "Access", hintText: "Access Type",
dropdownOptions: const ["Full", "Partial"], dropdownOptions: const ["Full", "Partial"],
required: true, editable: true,
editable: false, enableSearch: true,
enableSearch: false, validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
), ),
const SizedBox(height: 20.0), const SizedBox(height: 20.0),
Center( 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_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_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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_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'; import 'package:mzansi_innovation_hub/mih_env/env.dart';
@@ -332,30 +333,43 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
}, },
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
Row( MihToggle(
mainAxisAlignment: MainAxisAlignment.start, hintText: "Activate Business Account",
crossAxisAlignment: CrossAxisAlignment.center, initialPostion: businessUser,
children: [ fillColor:
const Text( MzanziInnovationHub.of(context)!.theme.secondaryColor(),
"Activate Business Account", secondaryFillColor:
style: TextStyle( MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontWeight: FontWeight.bold, onChange: (value) {
fontSize: 20,
),
),
const SizedBox(
width: 10,
),
Switch(
value: businessUser,
onChanged: (bool value) {
setState(() { setState(() {
businessUser = value; 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), const SizedBox(height: 30.0),
Center( Center(
child: MihButton( 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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.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_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_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_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_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_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_floating_menu.dart';
@@ -108,9 +108,15 @@ class _MihCardsState extends State<MihCards> {
MihForm( MihForm(
formKey: _formKey, formKey: _formKey,
formFields: [ formFields: [
MIHDropdownField( MihDropdownField(
controller: shopController, controller: shopController,
hintText: "Shop Name", hintText: "Shop Name",
editable: true,
enableSearch: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
requiredText: true,
dropdownOptions: const [ dropdownOptions: const [
"+More", "+More",
"Apple Tree", "Apple Tree",
@@ -157,9 +163,6 @@ class _MihCardsState extends State<MihCards> {
"Woermann Brock", "Woermann Brock",
"Woolworths" "Woolworths"
], ],
required: true,
editable: true,
enableSearch: false,
), ),
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: shopName, valueListenable: shopName,

View File

@@ -280,7 +280,7 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
visible: !hasAccess, visible: !hasAccess,
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
"Important Notice: Requesting Patient Profile Access", "Important Notice: Requesting Patient Profile Access",
@@ -343,9 +343,16 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
), ),
), ),
// const SizedBox(height: 15.0), // const SizedBox(height: 15.0),
Wrap(runSpacing: 10, spacing: 10, children: [ Center(
child: Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
runSpacing: 10,
spacing: 10,
children: [
Visibility( Visibility(
visible: hasAccess, visible: hasAccess,
child: Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
if (hasAccess) { if (hasAccess) {
@@ -362,22 +369,26 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
noAccessWarning(); noAccessWarning();
} }
}, },
buttonColor: buttonColor: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.successColor(), .theme
.successColor(),
width: 300, width: 300,
child: Text( child: Text(
"View Profile", "View Profile",
style: TextStyle( style: TextStyle(
color: color: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.primaryColor(), .theme
.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
), ),
),
Visibility( Visibility(
visible: !hasAccess && accessStatus == "No Access", visible: !hasAccess && accessStatus == "No Access",
child: Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
MIHApiCalls.addPatientAccessAPICall( MIHApiCalls.addPatientAccessAPICall(
@@ -394,22 +405,26 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
context, context,
); );
}, },
buttonColor: buttonColor: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.successColor(), .theme
.successColor(),
width: 300, width: 300,
child: Text( child: Text(
"Request Access", "Request Access",
style: TextStyle( style: TextStyle(
color: color: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.primaryColor(), .theme
.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
), ),
),
Visibility( Visibility(
visible: !hasAccess && accessStatus == "declined", visible: !hasAccess && accessStatus == "declined",
child: Center(
child: MihButton( child: MihButton(
onPressed: () { onPressed: () {
MIHApiCalls.reapplyPatientAccessAPICall( MIHApiCalls.reapplyPatientAccessAPICall(
@@ -424,20 +439,23 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
context, context,
); );
}, },
buttonColor: buttonColor: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.secondaryColor(), .theme
.secondaryColor(),
width: 300, width: 300,
child: Text( child: Text(
"Re-apply", "Re-apply",
style: TextStyle( style: TextStyle(
color: color: MzanziInnovationHub.of(context)!
MzanziInnovationHub.of(context)!.theme.primaryColor(), .theme
.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
), ),
),
Visibility( Visibility(
visible: !hasAccess && accessStatus == "pending", visible: !hasAccess && accessStatus == "pending",
child: const SizedBox( child: const SizedBox(
@@ -447,7 +465,9 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
"Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."), "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_api_calls.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_calendar_apis.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_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_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_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_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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_warning_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'; import 'package:mzansi_innovation_hub/mih_env/env.dart';
@@ -152,16 +152,22 @@ class _BuildPatientsListState extends State<BuildMyPatientListList> {
}, },
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDateField( MihDateField(
controller: dateController, controller: dateController,
lableText: "Date", labelText: "Date",
required: true, required: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10),
MIHTimeField( MihTimeField(
controller: timeController, controller: timeController,
lableText: "Time", labelText: "Time",
required: true, required: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 30.0), const SizedBox(height: 30.0),
Center( 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_objects/patients.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_manager/list_builders/build_mih_patient_search_list.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/material.dart';
import 'package:flutter/services.dart';
class MihPatientSearch extends StatefulWidget { class MihPatientSearch extends StatefulWidget {
final AppUser signedInUser; final AppUser signedInUser;
@@ -188,7 +187,6 @@ class _MihPatientSearchState extends State<MihPatientSearch> {
@override @override
void dispose() { void dispose() {
// TODO: implement dispose
super.dispose(); super.dispose();
_searchFocusNode.dispose(); _searchFocusNode.dispose();
_mihPatientSearchController.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_mzansi_calendar_apis.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.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_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_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_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_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_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_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_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_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_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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_env/env.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), const SizedBox(height: 10),
SizedBox( MihDateField(
// width: 500,
child: MIHDateField(
controller: _appointmentDateController, controller: _appointmentDateController,
lableText: "Date", labelText: "Date",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500,
child: MIHTimeField(
controller: _appointmentTimeController, controller: _appointmentTimeController,
lableText: "Time", labelText: "Time",
required: true, required: true,
), validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( 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/main.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.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_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_icd10_code_api.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_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_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_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_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_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_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_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_error_message.dart';
@@ -93,13 +91,15 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
MihForm( MihForm(
formKey: _formKey, formKey: _formKey,
formFields: [ formFields: [
MIHDropdownField( MihRadioOptions(
controller: _docTypeController, controller: _docTypeController,
hintText: "Document Type", hintText: "Document Type",
dropdownOptions: const ["Claim", "Statement"], fillColor:
required: true, MzanziInnovationHub.of(context)!.theme.secondaryColor(),
editable: true, secondaryFillColor:
enableSearch: false, MzanziInnovationHub.of(context)!.theme.primaryColor(),
requiredText: true,
radioOptions: const ["Claim", "Statement"],
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Center( Center(
@@ -118,23 +118,28 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
color: color:
MzanziInnovationHub.of(context)!.theme.secondaryColor()), MzanziInnovationHub.of(context)!.theme.secondaryColor()),
const SizedBox(height: 10), const SizedBox(height: 10),
MIHDateField( MihDateField(
controller: _serviceDateController, controller: _serviceDateController,
lableText: "Date of Service", labelText: "Date of Service",
required: true, required: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MIHDropdownField( MihRadioOptions(
controller: _serviceDescController, controller: _serviceDescController,
hintText: "Service Decription", hintText: "Serviced Description",
dropdownOptions: const [ fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
secondaryFillColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
requiredText: true,
radioOptions: const [
"Consultation", "Consultation",
"Procedure", "Procedure",
"Other", "Other",
], ],
required: true,
editable: true,
enableSearch: false,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
ValueListenableBuilder( ValueListenableBuilder(
@@ -144,29 +149,37 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
switch (value) { switch (value) {
case 'Consultation': case 'Consultation':
returnWidget = Column( returnWidget = Column(
key: const ValueKey('consultation_fields'), // Added key
children: [ children: [
SizedBox( MihRadioOptions(
child: MIHDropdownField( key: const ValueKey('consultation_type_dropdown'),
controller: _serviceDescOptionsController, controller: _serviceDescOptionsController,
hintText: "Consultation Type", hintText: "Consultation Type",
dropdownOptions: const [ fillColor: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
secondaryFillColor: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
requiredText: true,
radioOptions: const [
"General Consultation", "General Consultation",
"Follow-Up Consultation", "Follow-Up Consultation",
"Specialist Consultation", "Specialist Consultation",
"Emergency Consultation", "Emergency Consultation",
], ],
required: true,
editable: true,
enableSearch: false,
),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
); );
break;
case 'Procedure': case 'Procedure':
returnWidget = Column( returnWidget = Column(
key: const ValueKey('procedure_fields'), // Added key
children: [ children: [
MihTextFormField( MihTextFormField(
key: const ValueKey(
'procedure_name_field'), // Added key
fillColor: MzanziInnovationHub.of(context)! fillColor: MzanziInnovationHub.of(context)!
.theme .theme
.secondaryColor(), .secondaryColor(),
@@ -183,6 +196,8 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
MihTextFormField( MihTextFormField(
key: const ValueKey(
'procedure_additional_info_field'), // Added key
fillColor: MzanziInnovationHub.of(context)! fillColor: MzanziInnovationHub.of(context)!
.theme .theme
.secondaryColor(), .secondaryColor(),
@@ -192,7 +207,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
controller: _proceedureAdditionalInfoController, controller: _proceedureAdditionalInfoController,
multiLineInput: false, multiLineInput: false,
requiredText: true, requiredText: true,
hintText: "Additional Information", hintText: "Additional Procedure Information",
validator: (value) { validator: (value) {
return MihValidationServices().isEmpty(value); return MihValidationServices().isEmpty(value);
}, },
@@ -200,10 +215,14 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
const SizedBox(height: 15), const SizedBox(height: 15),
], ],
); );
break;
case 'Other': case 'Other':
returnWidget = Column( returnWidget = Column(
key: const ValueKey('other_fields'), // Added key
children: [ children: [
MihTextFormField( MihTextFormField(
key: const ValueKey(
'other_service_description_field'), // Added key
fillColor: MzanziInnovationHub.of(context)! fillColor: MzanziInnovationHub.of(context)!
.theme .theme
.secondaryColor(), .secondaryColor(),
@@ -221,8 +240,10 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
); );
break;
default: default:
returnWidget = const SizedBox(); returnWidget = const SizedBox(
key: const ValueKey('empty_fields')); // Added key
} }
return returnWidget; return returnWidget;
}, },
@@ -233,7 +254,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text("ICD-10 Code & Description", child: Text("ICD-10 Code & Description",
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)! color: MzanziInnovationHub.of(context)!
.theme .theme
@@ -384,16 +405,25 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
} }
void serviceDescriptionSelected() { void serviceDescriptionSelected() {
if (_serviceDescController.text.isNotEmpty) { String selectedType = _serviceDescController.text;
serviceDesc.value = _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 { } else {
serviceDesc.value = ""; _prcedureNameController.clear();
_proceedureAdditionalInfoController.clear();
_serviceDescOptionsController.clear();
} }
} }
void hasMedAid() { void hasMedAid() {
if (_medAidController.text.isNotEmpty) { if (_medAidController.text.isNotEmpty) {
medAid.value = _medAidController.text;
} else { } else {
medAid.value = ""; medAid.value = "";
} }
@@ -403,12 +433,26 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
if (_docTypeController.text.isEmpty || if (_docTypeController.text.isEmpty ||
_serviceDateController.text.isEmpty || _serviceDateController.text.isEmpty ||
_icd10CodeController.text.isEmpty || _icd10CodeController.text.isEmpty ||
_amountController.text.isEmpty || _amountController.text.isEmpty) {
_serviceDescOptionsController.text.isEmpty) {
return false; 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() { String getUserTitle() {
@@ -446,12 +490,18 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
_icd10CodeController.dispose(); _icd10CodeController.dispose();
_preauthNoController.dispose(); _preauthNoController.dispose();
_searchFocusNode.dispose(); _searchFocusNode.dispose();
serviceDesc.dispose();
medAid.dispose();
super.dispose(); super.dispose();
} }
@override @override
void initState() { void initState() {
super.initState();
_serviceDescController.text = "Consultation";
_serviceDescController.addListener(serviceDescriptionSelected); _serviceDescController.addListener(serviceDescriptionSelected);
serviceDesc.value = "Consultation";
_medAidController.addListener(hasMedAid); _medAidController.addListener(hasMedAid);
_fullNameController.text = _fullNameController.text =
"${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}"; "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}";
@@ -466,7 +516,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
"${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}"; "${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}";
_practiceNoController.text = widget.business!.practice_no; _practiceNoController.text = widget.business!.practice_no;
_vatNoController.text = widget.business!.vat_no; _vatNoController.text = widget.business!.vat_no;
super.initState(); hasMedAid();
} }
@override @override

View File

@@ -1,10 +1,12 @@
import 'dart:convert'; import 'dart:convert';
import 'package:mzansi_innovation_hub/main.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_package_components/mih_button.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_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_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_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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.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/patients.dart';
import 'package:mzansi_innovation_hub/mih_objects/perscription.dart'; import 'package:mzansi_innovation_hub/mih_objects/perscription.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/http.dart' as http;
class PrescripInput extends StatefulWidget { class PrescripInput extends StatefulWidget {
@@ -55,6 +56,7 @@ class PrescripInput extends StatefulWidget {
class _PrescripInputState extends State<PrescripInput> { class _PrescripInputState extends State<PrescripInput> {
final FocusNode _focusNode = FocusNode(); final FocusNode _focusNode = FocusNode();
final FocusNode _searchFocusNode = FocusNode(); final FocusNode _searchFocusNode = FocusNode();
final _formKey = GlobalKey<FormState>();
List<Perscription> perscriptionObjOutput = []; List<Perscription> perscriptionObjOutput = [];
late double width; late double width;
late double height; late double height;
@@ -214,12 +216,7 @@ class _PrescripInputState extends State<PrescripInput> {
} }
bool isFieldsFilled() { bool isFieldsFilled() {
if (widget.medicineController.text.isEmpty || 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) {
return false; return false;
} else { } else {
return true; return true;
@@ -351,13 +348,15 @@ class _PrescripInputState extends State<PrescripInput> {
Widget displayMedInput() { Widget displayMedInput() {
return Column( return Column(
children: [ children: [
//const SizedBox(height: 25.0), MihForm(
formKey: _formKey,
formFields: [
MihSearchBar( MihSearchBar(
controller: widget.medicineController, controller: widget.medicineController,
hintText: "Search Medicine", hintText: "Search Medicine",
prefixIcon: Icons.search, prefixIcon: Icons.search,
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () { onPrefixIconTap: () {
getMedsPopUp(widget.medicineController); getMedsPopUp(widget.medicineController);
@@ -368,75 +367,97 @@ class _PrescripInputState extends State<PrescripInput> {
searchFocusNode: _searchFocusNode, searchFocusNode: _searchFocusNode,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MihNumericStepper(
MIHDropdownField(
controller: widget.dosageController, controller: widget.dosageController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "Dosage", hintText: "Dosage",
dropdownOptions: numberOptions, requiredText: true,
required: true, minValue: 1,
editable: true, // maxValue: 5,
enableSearch: false, validationOn: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihNumericStepper(
controller: widget.timesDailyController, controller: widget.timesDailyController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "Times Daily", hintText: "Times Daily",
dropdownOptions: numberOptions, requiredText: true,
required: true, minValue: 1,
editable: true, // maxValue: 5,
enableSearch: false, validationOn: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihNumericStepper(
controller: widget.noDaysController, controller: widget.noDaysController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "No. Days", hintText: "No. Days",
dropdownOptions: numberOptions, requiredText: true,
required: true, minValue: 1,
editable: true, // maxValue: 5,
enableSearch: false, validationOn: true,
), ),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihNumericStepper(
controller: widget.noRepeatsController, controller: widget.noRepeatsController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "No.Repeats", hintText: "No.Repeats",
dropdownOptions: numberOptions, requiredText: true,
required: true, minValue: 0,
editable: true, // maxValue: 5,
enableSearch: false, validationOn: true,
), ),
const SizedBox(height: 15.0), const SizedBox(height: 15.0),
MihButton( Center(
child: MihButton(
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) {
if (isFieldsFilled()) { if (isFieldsFilled()) {
setState(() { setState(() {
updatePerscriptionList(); updatePerscriptionList();
widget.medicineController.clear(); widget.medicineController.clear();
widget.quantityController.clear(); widget.quantityController.text = "1";
widget.dosageController.clear(); widget.dosageController.text = "1";
widget.timesDailyController.clear(); widget.timesDailyController.text = "1";
widget.noDaysController.clear(); widget.noDaysController.text = "1";
widget.noRepeatsController.clear(); widget.noRepeatsController.text = "0";
}); });
} else { } else {
showDialog( showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return const MIHErrorMessage(errorType: "Input Error"); return const MIHErrorMessage(
errorType: "Input Error");
}, },
); );
} }
} else {
MihAlertServices().formNotFilledCompletely(context);
}
}, },
buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300, width: 300,
child: Text( child: Text(
"Add", "Add",
style: TextStyle( style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.primaryColor(), color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
),
],
)
], ],
); );
} }
@@ -543,10 +564,8 @@ class _PrescripInputState extends State<PrescripInput> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var size = MediaQuery.of(context).size; var size = MediaQuery.of(context).size;
setState(() {
width = size.width; width = size.width;
height = size.height; height = size.height;
});
return Wrap( return Wrap(
direction: Axis.horizontal, direction: Axis.horizontal,
alignment: WrapAlignment.center, 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/business_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/claim_statement_file.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_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:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/list_builders/build_claim_statement_files_list.dart';
import 'package:flutter/material.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:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:mzansi_innovation_hub/main.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_apis/mih_file_api.dart';
import 'package:mzansi_innovation_hub/mih_components/med_cert_input.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_validation_services.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_file_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.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_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_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_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_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_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_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.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 noRepeatsController = TextEditingController();
final outputController = TextEditingController(); final outputController = TextEditingController();
late PlatformFile? selected; late PlatformFile? selected;
final _formKey = GlobalKey<FormState>();
final _formKey2 = GlobalKey<FormState>();
late String env; late String env;
Future<void> submitDocUploadForm() async { Future<void> submitDocUploadForm() async {
@@ -217,7 +222,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
} }
} }
void uploudFilePopUp() { void uploudFilePopUp(double width) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@@ -227,15 +232,42 @@ class _PatientDocumentsState extends State<PatientDocuments> {
onWindowTapClose: () { onWindowTapClose: () {
Navigator.pop(context); Navigator.pop(context);
}, },
windowBody: Column( 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: [ children: [
MIHFileField( 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, controller: selectedFileController,
hintText: "Select File", hintText: "Selected File",
editable: false, requiredText: true,
required: true, readOnly: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
),
const SizedBox(width: 10),
MihButton(
onPressed: () async { onPressed: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles( FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.custom, type: FileType.custom,
allowedExtensions: ['jpg', 'png', 'pdf'], allowedExtensions: ['jpg', 'png', 'pdf'],
withData: true, withData: true,
@@ -250,30 +282,15 @@ class _PatientDocumentsState extends State<PatientDocuments> {
selectedFileController.text = selectedFile.name; selectedFileController.text = selectedFile.name;
}); });
}, },
), buttonColor: MzanziInnovationHub.of(context)!
const SizedBox(height: 15), .theme
MihButton( .secondaryColor(),
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( child: Text(
"Add File", "Attach",
style: TextStyle( style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.primaryColor(), color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@@ -281,6 +298,38 @@ class _PatientDocumentsState extends State<PatientDocuments> {
), ),
], ],
), ),
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,24 +346,49 @@ class _PatientDocumentsState extends State<PatientDocuments> {
}, },
windowBody: Column( windowBody: Column(
children: [ children: [
Medcertinput( MihForm(
startDateController: startDateController, formKey: _formKey2,
endDateTextController: endDateTextController, formFields: [
retDateTextController: retDateTextController, 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), const SizedBox(height: 15.0),
MihButton( Center(
child: MihButton(
onPressed: () async { onPressed: () async {
if (isMedCertFieldsFilled()) { if (_formKey2.currentState!.validate()) {
await generateMedCert(); await generateMedCert();
//Navigator.pop(context); //Navigator.pop(context);
} else { } else {
showDialog( MihAlertServices().formNotFilledCompletely(context);
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
} }
}, },
buttonColor: buttonColor:
@@ -323,12 +397,17 @@ class _PatientDocumentsState extends State<PatientDocuments> {
child: Text( child: Text(
"Generate", "Generate",
style: TextStyle( style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.primaryColor(), color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
), ),
),
],
),
], ],
), ),
), ),
@@ -344,11 +423,11 @@ class _PatientDocumentsState extends State<PatientDocuments> {
windowTitle: "Create Prescription", windowTitle: "Create Prescription",
onWindowTapClose: () { onWindowTapClose: () {
medicineController.clear(); medicineController.clear();
quantityController.clear(); quantityController.text = "1";
dosageController.clear(); dosageController.text = "1";
timesDailyController.clear(); timesDailyController.text = "1";
noDaysController.clear(); noDaysController.text = "1";
noRepeatsController.clear(); noRepeatsController.text = "0";
Navigator.pop(context); Navigator.pop(context);
}, },
windowBody: Column( windowBody: Column(
@@ -391,7 +470,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
} }
} }
Widget getMenu() { Widget getMenu(double width) {
if (widget.type == "personal") { if (widget.type == "personal") {
return Positioned( return Positioned(
right: 10, right: 10,
@@ -415,7 +494,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
backgroundColor: backgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(), MzanziInnovationHub.of(context)!.theme.successColor(),
onTap: () { onTap: () {
uploudFilePopUp(); uploudFilePopUp(width);
}, },
) )
], ],
@@ -444,7 +523,7 @@ class _PatientDocumentsState extends State<PatientDocuments> {
backgroundColor: backgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(), MzanziInnovationHub.of(context)!.theme.successColor(),
onTap: () { onTap: () {
uploudFilePopUp(); uploudFilePopUp(width);
}, },
), ),
SpeedDialChild( 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) { void successPopUp(String message) {
showDialog( showDialog(
context: context, context: context,
@@ -603,13 +618,14 @@ class _PatientDocumentsState extends State<PatientDocuments> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return MihPackageToolBody( return MihPackageToolBody(
borderOn: false, borderOn: false,
bodyItem: getBody(), bodyItem: getBody(screenWidth),
); );
} }
Widget getBody() { Widget getBody(double width) {
return Stack( return Stack(
children: [ children: [
MihSingleChildScroll( 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_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_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_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/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
import 'package:mzansi_innovation_hub/mih_objects/patients.dart'; import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
@@ -39,8 +40,9 @@ class _PatientInfoState extends State<PatientInfo> {
final medMainMemController = TextEditingController(); final medMainMemController = TextEditingController();
final medAidCodeController = TextEditingController(); final medAidCodeController = TextEditingController();
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
double textFieldWidth = 500; double textFieldWidth = 300;
late String medAid; late String medAid;
late bool medAidPosition;
Widget getPatientDetailsField() { Widget getPatientDetailsField() {
return Center( return Center(
@@ -146,16 +148,37 @@ class _PatientInfoState extends State<PatientInfo> {
medAidDet.add( medAidDet.add(
SizedBox( SizedBox(
width: textFieldWidth, width: textFieldWidth,
child: MihTextFormField( child: MihToggle(
// 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", 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; bool req;
@@ -216,6 +239,7 @@ class _PatientInfoState extends State<PatientInfo> {
Visibility( Visibility(
visible: req, visible: req,
child: SizedBox( child: SizedBox(
width: textFieldWidth,
child: MihTextFormField( child: MihTextFormField(
// width: textFieldWidth, // width: textFieldWidth,
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
@@ -299,6 +323,11 @@ class _PatientInfoState extends State<PatientInfo> {
TextEditingValue(text: widget.selectedPatient.medical_aid_code); TextEditingValue(text: widget.selectedPatient.medical_aid_code);
medAid = widget.selectedPatient.medical_aid; medAid = widget.selectedPatient.medical_aid;
}); });
if (medAid == "Yes") {
medAidPosition = true;
} else {
medAidPosition = false;
}
super.initState(); super.initState();
} }

View File

@@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:mzansi_innovation_hub/main.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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_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_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.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_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_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_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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_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'; import 'package:mzansi_innovation_hub/mih_env/env.dart';
@@ -46,6 +46,8 @@ class _AddPatientState extends State<AddPatient> {
final medMainMemController = TextEditingController(); final medMainMemController = TextEditingController();
final medAidCodeController = TextEditingController(); final medAidCodeController = TextEditingController();
late bool medAidPosition;
late bool medMainMemberPosition;
final baseAPI = AppEnviroment.baseApiUrl; final baseAPI = AppEnviroment.baseApiUrl;
late int futureDocOfficeId; late int futureDocOfficeId;
//late bool medRequired; //late bool medRequired;
@@ -297,13 +299,26 @@ class _AddPatientState extends State<AddPatient> {
.theme .theme
.secondaryColor()), .secondaryColor()),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihToggle(
controller: medAidController,
hintText: "Medical Aid", hintText: "Medical Aid",
editable: true, initialPostion: medAidPosition,
required: true, fillColor:
enableSearch: false, MzanziInnovationHub.of(context)!.theme.secondaryColor(),
dropdownOptions: const ["Yes", "No"], secondaryFillColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
onChange: (value) {
if (value) {
setState(() {
medAidController.text = "Yes";
medAidPosition = value;
});
} else {
setState(() {
medAidController.text = "No";
medAidPosition = value;
});
}
},
), ),
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: medRequired, valueListenable: medRequired,
@@ -313,13 +328,28 @@ class _AddPatientState extends State<AddPatient> {
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihToggle(
controller: medMainMemController,
hintText: "Main Member", hintText: "Main Member",
editable: value, initialPostion: medMainMemberPosition,
required: value, fillColor: MzanziInnovationHub.of(context)!
enableSearch: false, .theme
dropdownOptions: const ["Yes", "No"], .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), const SizedBox(height: 10.0),
MihTextFormField( MihTextFormField(
@@ -520,7 +550,10 @@ class _AddPatientState extends State<AddPatient> {
fnameController.text = widget.signedInUser.fname; fnameController.text = widget.signedInUser.fname;
lnameController.text = widget.signedInUser.lname; lnameController.text = widget.signedInUser.lname;
emailController.text = widget.signedInUser.email; emailController.text = widget.signedInUser.email;
medAidPosition = false;
medMainMemberPosition = false;
medAidController.text = "No"; medAidController.text = "No";
medMainMemController.text = "No";
}); });
super.initState(); super.initState();
} }

View File

@@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:mzansi_innovation_hub/main.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_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_validation_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_action.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_body.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_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_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_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_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_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_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'; 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 apiUrlDelete = "${AppEnviroment.baseApiUrl}/patients/delete/";
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
late bool medAidPosition;
late bool medMainMemberPosition;
late int futureDocOfficeId; late int futureDocOfficeId;
late String userEmail; late String userEmail;
// bool medRequired = false; // bool medRequired = false;
@@ -511,13 +513,26 @@ class _EditPatientState extends State<EditPatient> {
.theme .theme
.secondaryColor()), .secondaryColor()),
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihToggle(
controller: medAidController,
hintText: "Medical Aid", hintText: "Medical Aid",
editable: true, initialPostion: medAidPosition,
required: true, fillColor:
enableSearch: false, MzanziInnovationHub.of(context)!.theme.secondaryColor(),
dropdownOptions: const ["Yes", "No"], secondaryFillColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
onChange: (value) {
if (value) {
setState(() {
medAidController.text = "Yes";
medAidPosition = value;
});
} else {
setState(() {
medAidController.text = "No";
medAidPosition = value;
});
}
},
), ),
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: medRequired, valueListenable: medRequired,
@@ -527,13 +542,28 @@ class _EditPatientState extends State<EditPatient> {
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 10.0), const SizedBox(height: 10.0),
MIHDropdownField( MihToggle(
controller: medMainMemController,
hintText: "Main Member", hintText: "Main Member",
editable: value, initialPostion: medMainMemberPosition,
required: value, fillColor: MzanziInnovationHub.of(context)!
enableSearch: false, .theme
dropdownOptions: const ["Yes", "No"], .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), const SizedBox(height: 10.0),
MihTextFormField( MihTextFormField(
@@ -747,6 +777,18 @@ class _EditPatientState extends State<EditPatient> {
medAidCodeController.text = widget.selectedPatient.medical_aid_code; 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(); super.initState();
} }