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,31 +100,34 @@ class _MihTextFormFieldState extends State<MihTextFormField> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Visibility(
mainAxisAlignment: MainAxisAlignment.spaceBetween, visible: widget.hintText != null,
children: [ child: Row(
Text( mainAxisAlignment: MainAxisAlignment.spaceBetween,
widget.hintText, children: [
textAlign: TextAlign.left, Text(
style: TextStyle( widget.hintText ?? "",
color: widget.fillColor, textAlign: TextAlign.left,
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
Visibility(
visible: !widget.requiredText,
child: Text(
"(Optional)",
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
color: widget.fillColor, color: widget.fillColor,
fontSize: 15, fontSize: 18,
fontWeight: FontWeight.bold, 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), const SizedBox(height: 4),
FormField<String>( FormField<String>(
@@ -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, controller: widget.dateController,
child: MIHDateField( labelText: "Date",
controller: widget.dateController, required: true,
lableText: "Date", validator: (value) {
required: true, return MihValidationServices().isEmpty(value);
), },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500, controller: widget.timeController,
child: MIHTimeField( labelText: "Time",
controller: widget.timeController, required: true,
lableText: "Time", validator: (value) {
required: true, 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, controller: _appointmentDateController,
child: MIHDateField( labelText: "Date",
controller: _appointmentDateController, required: true,
lableText: "Date", validator: (value) {
required: true, return MihValidationServices().isEmpty(value);
), },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500, controller: _appointmentTimeController,
child: MIHTimeField( labelText: "Time",
controller: _appointmentTimeController, required: true,
lableText: "Time", validator: (value) {
required: true, 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)!
.theme
.secondaryColor(),
secondaryFillColor:
MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
requiredText: true,
radioOptions: const [
'gemma3:4b', 'gemma3:4b',
], ],
required: true,
editable: true,
enableSearch: false,
), ),
), ),
], ],
), ),
const SizedBox(height: 15), const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 230,
child: MIHDropdownField(
controller: _ttsVoiceController,
hintText: "AI Voice",
dropdownOptions: _voicesString,
required: true,
editable: true,
enableSearch: false,
),
),
const SizedBox(width: 10),
Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
//color: MzanziInnovationHub.of(context)!.theme.successColor(),
decoration: BoxDecoration(
color: MzanziInnovationHub.of(context)!
.theme
.successColor(),
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
),
child: IconButton(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
onPressed: () {
print("Start TTS now");
_speakText(
"This is the sample of the Mzansi A.I Voice.");
},
icon: const Icon(Icons.volume_up),
),
),
),
],
),
const SizedBox(height: 15),
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,
icon: const Icon( requiredText: true,
Icons.remove, validator: (value) {
return MihValidationServices().isEmpty(value);
},
), ),
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
MihTextFormField( Container(
width: 200, // color: Colors.white,
fillColor: MzanziInnovationHub.of(context)! decoration: BoxDecoration(
.theme borderRadius: BorderRadius.circular(
.secondaryColor(), 25), // Optional: rounds the corners
inputColor: MzanziInnovationHub.of(context)! boxShadow: const [
.theme BoxShadow(
.primaryColor(), color: Color.fromARGB(60, 0, 0,
controller: _fontSizeController, 0), // 0.2 opacity = 51 in alpha (255 * 0.2)
multiLineInput: false, spreadRadius: -2,
requiredText: true, blurRadius: 10,
readOnly: true, offset: Offset(0, 5),
hintText: "Time", ),
],
),
child: Padding(
padding: const EdgeInsets.only(
top: 2.0,
left: 5.0,
),
child: SizedBox(
width: 50,
height: 50,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all<Color>(
MzanziInnovationHub.of(context)!
.theme
.successColor()),
),
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
iconSize: 25,
onPressed: () {
print("Start TTS now");
_speakText(
"This is the sample of the Mzansi A.I Voice.");
},
icon: const Icon(
Icons.volume_up,
),
),
),
),
), ),
const SizedBox(width: 10), ],
IconButton.filled( ),
onPressed: () { const SizedBox(height: 10),
setState(() { Row(
_chatFrontSize += 1; children: [
_fontSizeController.text = SizedBox(
_chatFrontSize.ceil().toString(); width: 300,
}); child: MihNumericStepper(
}, controller: _fontSizeController,
icon: const Icon( fillColor: MzanziInnovationHub.of(context)!
Icons.add, .theme
.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
hintText: "Font Size",
requiredText: true,
minValue: 1,
// maxValue: 5,
validationOn: true,
), ),
), ),
], ],
@@ -537,6 +542,12 @@ class _AiChatState extends State<AiChat> {
} }
} }
void fontSizeChanged() {
setState(() {
_chatFrontSize = double.parse(_fontSizeController.text);
});
}
@override @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,27 +663,75 @@ 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: IconButton.filled( child: Container(
iconSize: 20, // color: Colors.white,
onPressed: () { decoration: BoxDecoration(
if (_showModelOptions.value == true) { borderRadius:
setState(() { BorderRadius.circular(25), // Optional: rounds the corners
_showModelOptions.value = false; boxShadow: const [
}); BoxShadow(
} else { color: Color.fromARGB(
setState(() { 60, 0, 0, 0), // 0.2 opacity = 51 in alpha (255 * 0.2)
_showModelOptions.value = true; spreadRadius: -2,
}); blurRadius: 10,
} offset: Offset(0, 5),
}, ),
icon: const Icon( ],
Icons.settings, ),
child: Padding(
padding: const EdgeInsets.only(
top: 2.0,
left: 5.0,
),
child: SizedBox(
width: 40,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MzanziInnovationHub.of(context)!.theme.errorColor()),
),
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
iconSize: 20,
onPressed: () {
if (_showModelOptions.value == true) {
setState(() {
_showModelOptions.value = false;
});
} else {
setState(() {
_showModelOptions.value = true;
});
}
},
icon: const Icon(
Icons.close,
),
),
),
), ),
), ),
// IconButton.filled(
// iconSize: 20,
// onPressed: () {
// if (_showModelOptions.value == true) {
// setState(() {
// _showModelOptions.value = false;
// });
// } else {
// setState(() {
// _showModelOptions.value = true;
// });
// }
// },
// icon: const Icon(
// Icons.settings,
// ),
// ),
), ),
), ),
Positioned( Positioned(

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, setState(() {
), businessUser = value;
), });
const SizedBox( },
width: 10,
),
Switch(
value: businessUser,
onChanged: (bool value) {
setState(() {
businessUser = value;
});
},
),
],
), ),
// Row(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// const Text(
// "Activate Business Account",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 20,
// ),
// ),
// const SizedBox(
// width: 10,
// ),
// Switch(
// value: businessUser,
// onChanged: (bool value) {
// setState(() {
// businessUser = value;
// });
// },
// ),
// ],
// ),
const SizedBox(height: 30.0), 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,111 +343,131 @@ class _BuildPatientsListState extends State<BuildMihPatientSearchList> {
), ),
), ),
// const SizedBox(height: 15.0), // const SizedBox(height: 15.0),
Wrap(runSpacing: 10, spacing: 10, children: [ Center(
Visibility( child: Wrap(
visible: hasAccess, alignment: WrapAlignment.center,
child: MihButton( crossAxisAlignment: WrapCrossAlignment.center,
onPressed: () { runSpacing: 10,
if (hasAccess) { spacing: 10,
Navigator.of(context) children: [
.pushNamed('/patient-manager/patient', Visibility(
arguments: PatientViewArguments( visible: hasAccess,
widget.signedInUser, child: Center(
widget.patients[index], child: MihButton(
widget.businessUser, onPressed: () {
widget.business, if (hasAccess) {
"business", Navigator.of(context)
)); .pushNamed('/patient-manager/patient',
} else { arguments: PatientViewArguments(
noAccessWarning(); widget.signedInUser,
} widget.patients[index],
}, widget.businessUser,
buttonColor: widget.business,
MzanziInnovationHub.of(context)!.theme.successColor(), "business",
width: 300, ));
child: Text( } else {
"View Profile", noAccessWarning();
style: TextStyle( }
color: },
MzanziInnovationHub.of(context)!.theme.primaryColor(), buttonColor: MzanziInnovationHub.of(context)!
fontSize: 20, .theme
fontWeight: FontWeight.bold, .successColor(),
), width: 300,
), child: Text(
), "View Profile",
), style: TextStyle(
Visibility( color: MzanziInnovationHub.of(context)!
visible: !hasAccess && accessStatus == "No Access", .theme
child: MihButton( .primaryColor(),
onPressed: () { fontSize: 20,
MIHApiCalls.addPatientAccessAPICall( fontWeight: FontWeight.bold,
widget.business!.business_id, ),
widget.patients[index].app_id, ),
"patient",
widget.business!.Name,
widget.personalSelected,
BusinessArguments(
widget.signedInUser,
widget.businessUser,
widget.business,
), ),
context,
);
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
width: 300,
child: Text(
"Request Access",
style: TextStyle(
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), ),
), Visibility(
), visible: !hasAccess && accessStatus == "No Access",
Visibility( child: Center(
visible: !hasAccess && accessStatus == "declined", child: MihButton(
child: MihButton( onPressed: () {
onPressed: () { MIHApiCalls.addPatientAccessAPICall(
MIHApiCalls.reapplyPatientAccessAPICall( widget.business!.business_id,
widget.business!.business_id, widget.patients[index].app_id,
widget.patients[index].app_id, "patient",
widget.personalSelected, widget.business!.Name,
BusinessArguments( widget.personalSelected,
widget.signedInUser, BusinessArguments(
widget.businessUser, widget.signedInUser,
widget.business, widget.businessUser,
widget.business,
),
context,
);
},
buttonColor: MzanziInnovationHub.of(context)!
.theme
.successColor(),
width: 300,
child: Text(
"Request Access",
style: TextStyle(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
), ),
context,
);
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300,
child: Text(
"Re-apply",
style: TextStyle(
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), ),
), Visibility(
visible: !hasAccess && accessStatus == "declined",
child: Center(
child: MihButton(
onPressed: () {
MIHApiCalls.reapplyPatientAccessAPICall(
widget.business!.business_id,
widget.patients[index].app_id,
widget.personalSelected,
BusinessArguments(
widget.signedInUser,
widget.businessUser,
widget.business,
),
context,
);
},
buttonColor: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
width: 300,
child: Text(
"Re-apply",
style: TextStyle(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
),
Visibility(
visible: !hasAccess && accessStatus == "pending",
child: const SizedBox(
width: 500,
//height: 50,
child: Text(
"Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."),
),
),
],
), ),
Visibility( ),
visible: !hasAccess && accessStatus == "pending",
child: const SizedBox(
width: 500,
//height: 50,
child: Text(
"Patient has not approved access to their profile. Once access has been approved you can book and appointment or view their profile."),
),
),
])
], ],
), ),
), ),

View File

@@ -3,12 +3,12 @@ import 'package:mzansi_innovation_hub/mih_apis/mih_alert_services.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_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, controller: _appointmentDateController,
child: MIHDateField( labelText: "Date",
controller: _appointmentDateController, required: true,
lableText: "Date", validator: (value) {
required: true, return MihValidationServices().isEmpty(value);
), },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
SizedBox( MihTimeField(
// width: 500, controller: _appointmentTimeController,
child: MIHTimeField( labelText: "Time",
controller: _appointmentTimeController, required: true,
lableText: "Time", validator: (value) {
required: true, 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)!
"General Consultation", .theme
"Follow-Up Consultation", .secondaryColor(),
"Specialist Consultation", secondaryFillColor: MzanziInnovationHub.of(context)!
"Emergency Consultation", .theme
], .primaryColor(),
required: true, requiredText: true,
editable: true, radioOptions: const [
enableSearch: false, "General Consultation",
), "Follow-Up Consultation",
"Specialist Consultation",
"Emergency Consultation",
],
), ),
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,92 +348,116 @@ class _PrescripInputState extends State<PrescripInput> {
Widget displayMedInput() { Widget displayMedInput() {
return Column( return Column(
children: [ children: [
//const SizedBox(height: 25.0), MihForm(
formKey: _formKey,
MihSearchBar( formFields: [
controller: widget.medicineController, MihSearchBar(
hintText: "Search Medicine", controller: widget.medicineController,
prefixIcon: Icons.search, hintText: "Search Medicine",
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), prefixIcon: Icons.search,
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), fillColor:
onPrefixIconTap: () { MzanziInnovationHub.of(context)!.theme.secondaryColor(),
getMedsPopUp(widget.medicineController); hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
}, onPrefixIconTap: () {
onClearIconTap: () { getMedsPopUp(widget.medicineController);
widget.medicineController.clear(); },
}, onClearIconTap: () {
searchFocusNode: _searchFocusNode,
),
const SizedBox(height: 10.0),
MIHDropdownField(
controller: widget.dosageController,
hintText: "Dosage",
dropdownOptions: numberOptions,
required: true,
editable: true,
enableSearch: false,
),
const SizedBox(height: 10.0),
MIHDropdownField(
controller: widget.timesDailyController,
hintText: "Times Daily",
dropdownOptions: numberOptions,
required: true,
editable: true,
enableSearch: false,
),
const SizedBox(height: 10.0),
MIHDropdownField(
controller: widget.noDaysController,
hintText: "No. Days",
dropdownOptions: numberOptions,
required: true,
editable: true,
enableSearch: false,
),
const SizedBox(height: 10.0),
MIHDropdownField(
controller: widget.noRepeatsController,
hintText: "No. Repeats",
dropdownOptions: numberOptions,
required: true,
editable: true,
enableSearch: false,
),
const SizedBox(height: 15.0),
MihButton(
onPressed: () {
if (isFieldsFilled()) {
setState(() {
updatePerscriptionList();
widget.medicineController.clear(); widget.medicineController.clear();
widget.quantityController.clear(); },
widget.dosageController.clear(); searchFocusNode: _searchFocusNode,
widget.timesDailyController.clear();
widget.noDaysController.clear();
widget.noRepeatsController.clear();
});
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
}
},
buttonColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300,
child: Text(
"Add",
style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), const SizedBox(height: 10.0),
), MihNumericStepper(
controller: widget.dosageController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "Dosage",
requiredText: true,
minValue: 1,
// maxValue: 5,
validationOn: true,
),
const SizedBox(height: 10.0),
MihNumericStepper(
controller: widget.timesDailyController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "Times Daily",
requiredText: true,
minValue: 1,
// maxValue: 5,
validationOn: true,
),
const SizedBox(height: 10.0),
MihNumericStepper(
controller: widget.noDaysController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "No. Days",
requiredText: true,
minValue: 1,
// maxValue: 5,
validationOn: true,
),
const SizedBox(height: 10.0),
MihNumericStepper(
controller: widget.noRepeatsController,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
inputColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
hintText: "No.Repeats",
requiredText: true,
minValue: 0,
// maxValue: 5,
validationOn: true,
),
const SizedBox(height: 15.0),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
if (isFieldsFilled()) {
setState(() {
updatePerscriptionList();
widget.medicineController.clear();
widget.quantityController.text = "1";
widget.dosageController.text = "1";
widget.timesDailyController.text = "1";
widget.noDaysController.text = "1";
widget.noRepeatsController.text = "0";
});
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Input Error");
},
);
}
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300,
child: Text(
"Add",
style: TextStyle(
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
)
], ],
); );
} }
@@ -543,10 +564,8 @@ class _PrescripInputState extends State<PrescripInput> {
@override @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,59 +232,103 @@ class _PatientDocumentsState extends State<PatientDocuments> {
onWindowTapClose: () { onWindowTapClose: () {
Navigator.pop(context); Navigator.pop(context);
}, },
windowBody: Column( windowBody: Padding(
children: [ padding:
MIHFileField( MzanziInnovationHub.of(context)!.theme.screenType == "desktop"
controller: selectedFileController, ? EdgeInsets.symmetric(horizontal: width * 0.05)
hintText: "Select File", : const EdgeInsets.symmetric(horizontal: 0),
editable: false, child: Column(
required: true, mainAxisAlignment: MainAxisAlignment.center,
onPressed: () async { children: [
FilePickerResult? result = await FilePicker.platform.pickFiles( MihForm(
type: FileType.custom, formKey: _formKey,
allowedExtensions: ['jpg', 'png', 'pdf'], formFields: [
withData: true, Row(
); crossAxisAlignment: CrossAxisAlignment.end,
if (result == null) return; children: [
final selectedFile = result.files.first; Expanded(
print("Selected file: $selectedFile"); child: MihTextFormField(
setState(() { fillColor: MzanziInnovationHub.of(context)!
selected = selectedFile; .theme
}); .secondaryColor(),
setState(() { inputColor: MzanziInnovationHub.of(context)!
selectedFileController.text = selectedFile.name; .theme
}); .primaryColor(),
}, controller: selectedFileController,
), hintText: "Selected File",
const SizedBox(height: 15), requiredText: true,
MihButton( readOnly: true,
onPressed: () { validator: (value) {
if (isFileFieldsFilled()) { return MihValidationServices().isEmpty(value);
submitDocUploadForm(); },
// uploadSelectedFile(selected); ),
Navigator.pop(context); ),
} else { const SizedBox(width: 10),
showDialog( MihButton(
context: context, onPressed: () async {
builder: (context) { FilePickerResult? result =
return const MIHErrorMessage(errorType: "Input Error"); await FilePicker.platform.pickFiles(
}, type: FileType.custom,
); allowedExtensions: ['jpg', 'png', 'pdf'],
} withData: true,
}, );
buttonColor: if (result == null) return;
MzanziInnovationHub.of(context)!.theme.secondaryColor(), final selectedFile = result.files.first;
width: 300, print("Selected file: $selectedFile");
child: Text( setState(() {
"Add File", selected = selectedFile;
style: TextStyle( });
color: MzanziInnovationHub.of(context)!.theme.primaryColor(), setState(() {
fontSize: 20, selectedFileController.text = selectedFile.name;
fontWeight: FontWeight.bold, });
), },
buttonColor: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
child: Text(
"Attach",
style: TextStyle(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 20),
Center(
child: MihButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
submitDocUploadForm();
// uploadSelectedFile(selected);
Navigator.pop(context);
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
width: 300,
child: Text(
"Add File",
style: TextStyle(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
), ),
), ],
], ),
), ),
), ),
); );
@@ -297,37 +346,67 @@ class _PatientDocumentsState extends State<PatientDocuments> {
}, },
windowBody: Column( windowBody: Column(
children: [ children: [
Medcertinput( MihForm(
startDateController: startDateController, formKey: _formKey2,
endDateTextController: endDateTextController, formFields: [
retDateTextController: retDateTextController, MihDateField(
), controller: startDateController,
const SizedBox(height: 15.0), labelText: "From",
MihButton( required: true,
onPressed: () async { validator: (value) {
if (isMedCertFieldsFilled()) { return MihValidationServices().isEmpty(value);
await generateMedCert(); },
//Navigator.pop(context);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
}
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300,
child: Text(
"Generate",
style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
), ),
), const SizedBox(height: 10.0),
MihDateField(
controller: endDateTextController,
labelText: "Up to Including",
required: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
const SizedBox(height: 10.0),
MihDateField(
controller: retDateTextController,
labelText: "Return",
required: true,
validator: (value) {
return MihValidationServices().isEmpty(value);
},
),
// Medcertinput(
// startDateController: startDateController,
// endDateTextController: endDateTextController,
// retDateTextController: retDateTextController,
// ),
const SizedBox(height: 15.0),
Center(
child: MihButton(
onPressed: () async {
if (_formKey2.currentState!.validate()) {
await generateMedCert();
//Navigator.pop(context);
} else {
MihAlertServices().formNotFilledCompletely(context);
}
},
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
width: 300,
child: Text(
"Generate",
style: TextStyle(
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
), ),
], ],
), ),
@@ -344,11 +423,11 @@ class _PatientDocumentsState extends State<PatientDocuments> {
windowTitle: "Create Prescription", 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();
} }