Merge pull request #188 from yaso-meth/QOL--New-Search-Bar

QOL--New-Search-Bar
This commit is contained in:
yaso-meth
2025-05-30 14:47:28 +02:00
committed by GitHub
13 changed files with 466 additions and 268 deletions

View File

@@ -11,6 +11,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_image_display.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
class PackageToolOne extends StatefulWidget {
const PackageToolOne({super.key});
@@ -25,6 +26,8 @@ class _PackageToolOneState extends State<PackageToolOne> {
PlatformFile? imageFile;
TextEditingController _fileNameController = TextEditingController();
TextEditingController _imagefileController = TextEditingController();
TextEditingController _searchController = TextEditingController();
final FocusNode searchFocusNode = FocusNode();
void showTestFullWindow() {
showDialog(
context: context,
@@ -80,6 +83,23 @@ class _PackageToolOneState extends State<PackageToolOne> {
);
}
@override
Widget build(BuildContext context) {
return MihPackageToolBody(
borderOn: true,
bodyItem: getBody(),
);
}
@override
void dispose() {
_fileNameController.dispose();
_imagefileController.dispose();
_searchController.dispose();
searchFocusNode.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
@@ -90,14 +110,6 @@ class _PackageToolOneState extends State<PackageToolOne> {
});
}
@override
Widget build(BuildContext context) {
return MihPackageToolBody(
borderOn: true,
bodyItem: getBody(),
);
}
Widget getBody() {
return Stack(
children: [
@@ -123,7 +135,24 @@ class _PackageToolOneState extends State<PackageToolOne> {
),
],
),
const SizedBox(height: 10),
const SizedBox(height: 20),
MihSearchBar(
controller: _searchController,
hintText: "Ask Mzansi",
// prefixIcon: Icons.search,
prefixIcon: Icons.search,
prefixAltIcon: MihIcons.mzansiAi,
width: 300,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Icon Pressed: ${_searchController.text}");
},
searchFocusNode: searchFocusNode,
),
const SizedBox(height: 20),
MihButton(
onPressed: () {
print("Button Pressed");

View File

@@ -0,0 +1,170 @@
import 'package:flutter/material.dart';
class MihSearchBar extends StatefulWidget {
final TextEditingController controller;
final String hintText;
final IconData prefixIcon;
final IconData? prefixAltIcon;
final List<Widget>? suffixTools;
final double? width;
final double? height;
final Color fillColor;
final Color hintColor;
final void Function()? onPrefixIconTap;
final void Function()? onClearIconTap;
final double? elevation;
final FocusNode searchFocusNode;
const MihSearchBar({
Key? key,
required this.controller,
required this.hintText,
required this.prefixIcon,
this.prefixAltIcon,
this.suffixTools,
this.width,
this.height,
required this.fillColor,
required this.hintColor,
required this.onPrefixIconTap,
this.onClearIconTap,
this.elevation,
required this.searchFocusNode,
}) : super(key: key);
@override
State<MihSearchBar> createState() => _MihSearchBarState();
}
class _MihSearchBarState extends State<MihSearchBar> {
bool _showClearIcon = false;
Widget getPrefixIcon() {
if (_showClearIcon) {
// If the clear icon is shown and an alternative prefix icon is provided, use it
return widget.prefixAltIcon != null
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(
widget.prefixAltIcon,
color: widget.hintColor,
size: 35,
),
)
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(
Icons.search,
color: widget.hintColor,
size: 35,
),
); // Default to search icon if no alt icon
} else {
// Return the primary prefix icon or the alternative if provided
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Icon(
Icons.search,
color: widget.hintColor,
size: 35,
),
);
}
}
@override
void initState() {
super.initState();
// 1. Add the listener to the controller
widget.controller.addListener(_updateClearIconVisibility);
// 2. Initialize the clear icon visibility based on the current text
_updateClearIconVisibility();
}
@override
void dispose() {
widget.controller.removeListener(_updateClearIconVisibility);
super.dispose();
}
void _updateClearIconVisibility() {
if (!mounted) {
return;
}
final bool shouldShow = widget.controller.text.isNotEmpty;
// Only call setState if the visibility state actually changes
if (_showClearIcon != shouldShow) {
setState(() {
_showClearIcon = shouldShow;
});
}
}
@override
Widget build(BuildContext context) {
return Material(
elevation: widget.elevation ?? 4.0, // Use provided elevation or default
borderRadius: BorderRadius.circular(30.0),
color: widget.fillColor,
child: AnimatedContainer(
// Keep AnimatedContainer for width/height transitions
width: widget.width,
height: widget.height ?? 50,
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
),
child: Theme(
data: Theme.of(context).copyWith(
textSelectionTheme: TextSelectionThemeData(
selectionColor: widget.hintColor.withValues(alpha: 0.3),
selectionHandleColor: widget.hintColor,
),
),
child: TextField(
controller: widget.controller, // Assign the controller
focusNode: widget.searchFocusNode,
style: TextStyle(
color: widget.hintColor,
fontWeight: FontWeight.w600,
),
cursorColor: widget.hintColor,
decoration: InputDecoration(
hintText: widget.hintText,
hintStyle: TextStyle(
color: widget.hintColor,
fontWeight: FontWeight.bold,
),
border: InputBorder.none,
contentPadding:
const EdgeInsets.symmetric(horizontal: 20.0, vertical: 12.0),
prefixIcon: GestureDetector(
onTap: widget.onPrefixIconTap,
child: getPrefixIcon(),
),
suffixIcon: Row(
// Use a Row for multiple suffix icons
mainAxisSize: MainAxisSize.min,
children: [
// Optional suffix tools
if (widget.suffixTools != null) ...widget.suffixTools!,
// Clear Icon (conditionally visible)
if (_showClearIcon) // Only show if input is not empty
IconButton(
icon: Icon(Icons.clear,
color: widget.hintColor), // Clear icon
onPressed: widget.onClearIconTap ??
() {
widget.controller.clear();
// No need for setState here, _updateClearIconVisibility will handle it
},
),
],
),
),
),
),
),
);
}
}

View File

@@ -3,7 +3,9 @@ import 'dart:convert';
// import 'dart:convert';
import 'package:flutter_speed_dial/flutter_speed_dial.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_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_objects/patients.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -15,7 +17,6 @@ import 'package:supertokens_flutter/http.dart' as http;
import "package:universal_html/html.dart" as html;
import '../../mih_apis/mih_location_api.dart';
import '../../mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import '../../mih_components/mih_layout/mih_action.dart';
import 'components/mih_app_drawer.dart';
import '../../mih_components/mih_layout/mih_body.dart';
@@ -1082,16 +1083,22 @@ class _MIHHomeLegacyState extends State<MIHHomeLegacy> {
}
},
child: SizedBox(
child: MIHSearchField(
child: MihSearchBar(
controller: searchController,
hintText: "Search Mzansi Packages",
required: false,
editable: true,
onTap: () {
hintText: "Ask Mzansi",
prefixIcon: Icons.search,
prefixAltIcon: MihIcons.mzansiAi,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Text: ${searchController.text}");
setState(() {
appSearch = searchController.text;
});
},
searchFocusNode: FocusNode(),
),
),
),

View File

@@ -1,7 +1,8 @@
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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_search_bar.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/business.dart';
@@ -43,6 +44,7 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
double packageSize = 200;
late final AnimationController _marqueeController;
late final ScrollController _scrollController;
final FocusNode _searchFocusNode = FocusNode();
final String maintenanceMsg =
"\tHeads up! We're doing maintenance on Thur, 15 May 2025 at 10 PM (CAT). MIH may be unavailable briefly.";
@@ -164,6 +166,9 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
super.dispose();
searchController.removeListener(searchPackage);
searchController.dispose();
_marqueeController.dispose();
_scrollController.dispose();
_searchFocusNode.dispose();
}
@override
@@ -199,40 +204,22 @@ class _MihBusinessHomeState extends State<MihBusinessHome>
return MihSingleChildScroll(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
flex: 4,
child: SizedBox(
child: MIHSearchField(
controller: searchController,
hintText: "Search MIH Packages",
required: false,
editable: true,
onTap: () {
setState(() {});
},
),
),
),
Flexible(
flex: 1,
child: IconButton(
//padding: const EdgeInsets.all(0),
onPressed: () {
setState(() {
searchController.clear();
});
},
icon: const Icon(
Icons.filter_alt_off,
size: 30,
),
),
),
],
const SizedBox(height: 10),
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: searchController,
hintText: "Ask Mzansi",
prefixIcon: Icons.search,
prefixAltIcon: MihIcons.mzansiAi,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Text: ${searchController.text}");
},
searchFocusNode: _searchFocusNode,
),
),
const SizedBox(height: 10),
ValueListenableBuilder(

View File

@@ -1,8 +1,9 @@
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.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_tile.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.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/business.dart';
@@ -51,6 +52,7 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
double packageSize = 200;
late final AnimationController _marqueeController;
late final ScrollController _scrollController;
final FocusNode _searchFocusNode = FocusNode();
final String maintenanceMsg =
"\tHeads up! We're doing maintenance on Thur, 15 May 2025 at 10 PM (CAT). MIH may be unavailable briefly.";
@@ -206,6 +208,7 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
super.dispose();
searchController.removeListener(searchPackage);
searchController.dispose();
_searchFocusNode.dispose();
_marqueeController.dispose();
_scrollController.dispose();
}
@@ -244,38 +247,22 @@ class _MihPersonalHomeState extends State<MihPersonalHome>
return MihSingleChildScroll(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
flex: 4,
child: SizedBox(
child: MIHSearchField(
controller: searchController,
hintText: "Search MIH Packages",
required: false,
editable: true,
onTap: () {},
),
),
),
Flexible(
flex: 1,
child: IconButton(
//padding: const EdgeInsets.all(0),
onPressed: () {
setState(() {
searchController.clear();
});
},
icon: const Icon(
Icons.filter_alt_off,
size: 30,
),
),
),
],
const SizedBox(height: 10),
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: searchController,
hintText: "Ask Mzansi",
prefixIcon: Icons.search,
prefixAltIcon: MihIcons.mzansiAi,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Text: ${searchController.text}");
},
searchFocusNode: _searchFocusNode,
),
),
const SizedBox(height: 10),
ValueListenableBuilder(

View File

@@ -1,9 +1,8 @@
import 'dart:convert';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_env/env.dart';
@@ -29,6 +28,7 @@ class _MihBusinessUserSearchState extends State<MihBusinessUserSearch> {
final FocusNode _focusNode = FocusNode();
final TextEditingController searchController = TextEditingController();
late Future<List<AppUser>> userSearchResults;
final FocusNode _searchFocusNode = FocusNode();
String userSearch = "";
String errorCode = "";
@@ -89,16 +89,25 @@ class _MihBusinessUserSearchState extends State<MihBusinessUserSearch> {
userSearchResults = fetchUsers("abc");
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_searchFocusNode.dispose();
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return MihPackageToolBody(
borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getBody(),
bodyItem: getBody(width),
);
}
Widget getBody() {
Widget getBody(double width) {
return MihSingleChildScroll(
child: KeyboardListener(
focusNode: _focusNode,
@@ -110,16 +119,21 @@ class _MihBusinessUserSearchState extends State<MihBusinessUserSearch> {
}
},
child: Column(mainAxisSize: MainAxisSize.max, children: [
MIHSearchField(
controller: searchController,
hintText: "Username or Email Search",
required: true,
editable: true,
onTap: () {
submitUserForm();
},
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: searchController,
hintText: "Search Users",
prefixIcon: Icons.search,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
submitUserForm();
},
searchFocusNode: _searchFocusNode,
),
),
//spacer
const SizedBox(height: 10),
FutureBuilder(
future: userSearchResults,

View File

@@ -3,10 +3,9 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_swipe_detector/flutter_swipe_detector.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import '../../../main.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../../../mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import '../../../mih_components/mih_layout/mih_action.dart';
import '../../../mih_components/mih_layout/mih_body.dart';
import '../../../mih_components/mih_layout/mih_header.dart';
@@ -35,6 +34,7 @@ class ManageBusinessProfile extends StatefulWidget {
class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
final FocusNode _focusNode = FocusNode();
final FocusNode _searchFocusNode = FocusNode();
final baseAPI = AppEnviroment.baseApiUrl;
final TextEditingController searchController = TextEditingController();
@@ -179,7 +179,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
}
}
Widget userSearchView() {
Widget userSearchView(double width) {
return KeyboardListener(
focusNode: _focusNode,
autofocus: true,
@@ -198,15 +198,21 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
const SizedBox(height: 10),
MIHSearchField(
controller: searchController,
hintText: "Username or Email Search",
required: true,
editable: true,
onTap: () {
submitUserForm();
},
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: searchController,
hintText: "Ask Mzansi",
prefixIcon: Icons.search,
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Text: ${searchController.text}");
},
searchFocusNode: _searchFocusNode,
),
),
//spacer
const SizedBox(height: 10),
FutureBuilder(
@@ -274,7 +280,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
);
}
Widget showSelection(int selectionIndex) {
Widget showSelection(int selectionIndex, double width, [double? height]) {
// if (selectionIndex == 0) {
// return BusinessDetails(arguments: widget.arguments);
// } else
@@ -283,7 +289,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
} else if (selectionIndex == 1) {
return employeesview();
} else {
return userSearchView();
return userSearchView(width);
}
}
@@ -412,11 +418,11 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
);
}
MIHBody getBody() {
MIHBody getBody(double width) {
return MIHBody(
borderOn: true,
bodyItems: [
showSelection(selectionIndex),
showSelection(selectionIndex, width),
],
);
}
@@ -425,6 +431,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
void dispose() {
searchController.dispose();
_focusNode.dispose();
_searchFocusNode.dispose();
super.dispose();
}
@@ -437,6 +444,8 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return SwipeDetector(
onSwipeLeft: (offset) {
if (selectionIndex < 2) {
@@ -458,7 +467,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
actionButton: getActionButton(),
secondaryActionButton: null,
header: getHeader(),
body: getBody(),
body: getBody(width),
actionDrawer: null,
secondaryActionDrawer: null,
bottomNavBar: null,

View File

@@ -3,13 +3,13 @@ import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_number_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_floating_menu.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.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_objects/app_user.dart';
@@ -35,6 +35,7 @@ class _MihCardsState extends State<MihCards> {
final TextEditingController _nicknameController = TextEditingController();
final TextEditingController cardNumberController = TextEditingController();
final TextEditingController cardSearchController = TextEditingController();
final FocusNode searchFocusNode = FocusNode();
late Future<List<MIHLoyaltyCard>> cardList;
List<MIHLoyaltyCard> listOfCards = [];
//bool showSelectedCardType = false;
@@ -253,6 +254,7 @@ class _MihCardsState extends State<MihCards> {
cardSearchController.dispose();
searchShopName.dispose();
_nicknameController.dispose();
searchFocusNode.dispose();
shopName.dispose();
super.dispose();
}
@@ -267,45 +269,36 @@ class _MihCardsState extends State<MihCards> {
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return MihPackageToolBody(
borderOn: false,
bodyItem: getBody(),
bodyItem: getBody(width),
);
}
Widget getBody() {
Widget getBody(double width) {
return Stack(
children: [
MihSingleChildScroll(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
flex: 4,
child: SizedBox(
height: 50,
child: MIHSearchField(
controller: cardSearchController,
hintText: "Shop Name",
required: false,
editable: true,
onTap: () {},
),
),
),
Flexible(
flex: 1,
child: IconButton(
onPressed: () {
FocusScope.of(context).unfocus();
cardSearchController.clear();
},
icon: const Icon(Icons.filter_alt_off),
),
),
],
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: cardSearchController,
hintText: "Search Cards",
// prefixIcon: Icons.search,
prefixIcon: Icons.search,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
print("Search Icon Pressed: ${cardSearchController.text}");
},
searchFocusNode: searchFocusNode,
),
),
const SizedBox(height: 10),
FutureBuilder(

View File

@@ -1,8 +1,8 @@
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_env/env.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
@@ -35,11 +35,12 @@ class MihPatientSearch extends StatefulWidget {
class _MihPatientSearchState extends State<MihPatientSearch> {
TextEditingController _mihPatientSearchController = TextEditingController();
final FocusNode _focusNode = FocusNode();
final FocusNode _searchFocusNode = FocusNode();
String _mihPatientSearchString = "";
String baseUrl = AppEnviroment.baseApiUrl;
late Future<List<Patient>> _mihPatientSearchResults;
Widget getPatientSearch() {
Widget getPatientSearch(double width) {
return MihSingleChildScroll(
child: KeyboardListener(
focusNode: _focusNode,
@@ -54,39 +55,30 @@ class _MihPatientSearchState extends State<MihPatientSearch> {
}
},
child: Column(mainAxisSize: MainAxisSize.max, children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
flex: 1,
child: MIHSearchField(
controller: _mihPatientSearchController,
hintText: "ID or Medical Aid No. Search",
required: false,
editable: true,
onTap: () {
// submitPatientForm();
submitPatientSearch();
//To-Do: Implement the search function
// print("To-Do: Implement the search function");
},
),
),
IconButton(
onPressed: () {
setState(() {
_mihPatientSearchController.clear();
_mihPatientSearchString = "";
});
submitPatientSearch();
//To-Do: Implement the search function
// print("To-Do: Implement the search function");
},
icon: const Icon(
Icons.filter_alt_off,
size: 25,
))
],
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: _mihPatientSearchController,
hintText: "Search by ID or Medical Aid No.",
prefixIcon: Icons.search,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
submitPatientSearch();
print("Search Text: ${_mihPatientSearchController.text}");
},
onClearIconTap: () {
setState(() {
_mihPatientSearchController.clear();
_mihPatientSearchString = "";
});
submitPatientSearch();
//To-Do: Implement the search function
// print("To-Do: Implement the search function");
},
searchFocusNode: _searchFocusNode,
),
),
//spacer
const SizedBox(height: 10),
@@ -211,12 +203,23 @@ class _MihPatientSearchState extends State<MihPatientSearch> {
_mihPatientSearchResults = MIHApiCalls.fetchPatients("abc");
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_searchFocusNode.dispose();
_mihPatientSearchController.dispose();
_focusNode.dispose();
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return MihPackageToolBody(
borderOn: false,
innerHorizontalPadding: 10,
bodyItem: getPatientSearch(),
bodyItem: getPatientSearch(width),
);
}
}

View File

@@ -1,8 +1,8 @@
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_apis/mih_api_calls.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_env/env.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
@@ -34,12 +34,13 @@ class MyPatientList extends StatefulWidget {
class _MyPatientListState extends State<MyPatientList> {
late Future<List<PatientAccess>> _myPatientList;
TextEditingController _myPatientSearchController = TextEditingController();
final FocusNode _searchFocusNode = FocusNode();
String _myPatientIdSearchString = "";
String baseUrl = AppEnviroment.baseApiUrl;
final FocusNode _focusNode = FocusNode();
Widget myPatientListTool() {
Widget myPatientListTool(double width) {
return MihSingleChildScroll(
child: KeyboardListener(
focusNode: _focusNode,
@@ -55,62 +56,31 @@ class _MyPatientListState extends State<MyPatientList> {
}
},
child: Column(mainAxisSize: MainAxisSize.max, children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// const Text(
// "My Patient List",
// style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
// ),
// IconButton(
// iconSize: 20,
// icon: const Icon(
// Icons.refresh,
// ),
// onPressed: () {
// getMyPatientList();
// },
// ),
// ],
// ),
// Divider(
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
// //spacer
// const SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
flex: 1,
child: MIHSearchField(
controller: _myPatientSearchController,
hintText: "Patient ID Search",
required: false,
editable: true,
onTap: () {
setState(() {
_myPatientIdSearchString =
_myPatientSearchController.text;
_myPatientList =
MIHApiCalls.getPatientAccessListOfBusiness(
widget.business!.business_id);
});
},
),
),
IconButton(
onPressed: () {
setState(() {
_myPatientSearchController.clear();
_myPatientIdSearchString = "";
});
getMyPatientList();
},
icon: const Icon(
Icons.filter_alt_off,
size: 25,
))
],
Padding(
padding: EdgeInsets.symmetric(horizontal: width / 20),
child: MihSearchBar(
controller: _myPatientSearchController,
hintText: "Search by ID",
prefixIcon: Icons.search,
fillColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
setState(() {
_myPatientIdSearchString = _myPatientSearchController.text;
_myPatientList = MIHApiCalls.getPatientAccessListOfBusiness(
widget.business!.business_id);
});
},
onClearIconTap: () {
setState(() {
_myPatientSearchController.clear();
_myPatientIdSearchString = "";
});
getMyPatientList();
},
searchFocusNode: _searchFocusNode,
),
),
//spacer
const SizedBox(height: 10),
@@ -199,12 +169,23 @@ class _MyPatientListState extends State<MyPatientList> {
widget.business!.business_id);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_myPatientSearchController.dispose();
_searchFocusNode.dispose();
_focusNode.dispose();
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.sizeOf(context);
final double width = size.width;
return MihPackageToolBody(
borderOn: false,
innerHorizontalPadding: 10,
bodyItem: myPatientListTool(),
bodyItem: myPatientListTool(width),
);
}
}

View File

@@ -1,12 +1,13 @@
import 'package:flutter/services.dart';
import 'package:mzansi_innovation_hub/main.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_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_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_text_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_package_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:mzansi_innovation_hub/mih_objects/app_user.dart';
import 'package:mzansi_innovation_hub/mih_objects/arguments.dart';
@@ -64,6 +65,8 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
final ValueNotifier<String> serviceDesc = ValueNotifier("");
final ValueNotifier<String> medAid = ValueNotifier("");
List<ICD10Code> icd10codeList = [];
final FocusNode _searchFocusNode = FocusNode();
final FocusNode _focusNode = FocusNode();
void icd10SearchWindow(List<ICD10Code> codeList) {
showDialog(
@@ -186,18 +189,35 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
},
),
//const SizedBox(height: 10),
MIHSearchField(
controller: _icd10CodeController,
hintText: "ICD-10 Code & Description",
required: true,
editable: true,
onTap: () {
//api
MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context)
.then((result) {
icd10SearchWindow(result);
});
KeyboardListener(
focusNode: _focusNode,
autofocus: true,
onKeyEvent: (event) async {
if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.enter) {
MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context)
.then((result) {
icd10SearchWindow(result);
});
}
},
child: MihSearchBar(
controller: _icd10CodeController,
hintText: "ICD-10 Code & Description",
prefixIcon: Icons.search,
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context)
.then((result) {
icd10SearchWindow(result);
});
},
onClearIconTap: () {
_icd10CodeController.clear();
},
searchFocusNode: _searchFocusNode,
),
),
const SizedBox(height: 10),
MIHTextField(
@@ -365,6 +385,7 @@ class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
_proceedureAdditionalInfoController.dispose();
_icd10CodeController.dispose();
_preauthNoController.dispose();
_searchFocusNode.dispose();
super.dispose();
}

View File

@@ -2,9 +2,9 @@ import 'dart:convert';
import 'package:mzansi_innovation_hub/main.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_search_bar.dart';
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/components/medicine_search.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_success_message.dart';
@@ -54,6 +54,7 @@ class PrescripInput extends StatefulWidget {
class _PrescripInputState extends State<PrescripInput> {
final FocusNode _focusNode = FocusNode();
final FocusNode _searchFocusNode = FocusNode();
List<Perscription> perscriptionObjOutput = [];
late double width;
late double height;
@@ -361,28 +362,23 @@ class _PrescripInputState extends State<PrescripInput> {
getMedsPopUp(widget.medicineController);
}
},
child: MIHSearchField(
child: MihSearchBar(
controller: widget.medicineController,
hintText: "Medicine",
required: true,
editable: true,
onTap: () {
hintText: "Search Medicine",
prefixIcon: Icons.search,
fillColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
hintColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
onPrefixIconTap: () {
getMedsPopUp(widget.medicineController);
},
onClearIconTap: () {
widget.medicineController.clear();
},
searchFocusNode: _searchFocusNode,
),
),
const SizedBox(height: 10.0),
// SizedBox(
// width: 300,
// child: MIHDropdownField(
// controller: widget.quantityController,
// hintText: "Quantity",
// dropdownOptions: numberOptions,
// required: true,
// editable: true,
// ),
// ),
// const SizedBox(height: 10.0),
MIHDropdownField(
controller: widget.dosageController,
hintText: "Dosage",
@@ -544,6 +540,7 @@ class _PrescripInputState extends State<PrescripInput> {
@override
void dispose() {
_focusNode.dispose();
_searchFocusNode.dispose();
super.dispose();
}

View File

@@ -423,8 +423,8 @@ class _PatientDocumentsState extends State<PatientDocuments> {
);
} else {
return Positioned(
right: 0,
bottom: 0,
right: 10,
bottom: 10,
child: MihFloatingMenu(
icon: Icons.add,
animatedIcon: AnimatedIcons.menu_close,