app files restructure
This commit is contained in:
38
Frontend/lib/mih_components/mih_layout/mih_action.dart
Normal file
38
Frontend/lib/mih_components/mih_layout/mih_action.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MIHAction extends StatefulWidget {
|
||||
final void Function()? onTap;
|
||||
final double iconSize;
|
||||
final Widget icon;
|
||||
const MIHAction({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.iconSize,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHAction> createState() => _MIHActionState();
|
||||
}
|
||||
|
||||
class _MIHActionState extends State<MIHAction> {
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
iconSize: widget.iconSize,
|
||||
padding: const EdgeInsets.all(0),
|
||||
onPressed: widget.onTap,
|
||||
icon: widget.icon,
|
||||
);
|
||||
}
|
||||
}
|
||||
267
Frontend/lib/mih_components/mih_layout/mih_app_drawer.dart
Normal file
267
Frontend/lib/mih_components/mih_layout/mih_app_drawer.dart
Normal file
@@ -0,0 +1,267 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
import '../../mih_objects/app_user.dart';
|
||||
import '../../mih_objects/arguments.dart';
|
||||
import 'package:supertokens_flutter/supertokens.dart';
|
||||
import '../mih_profile_picture.dart';
|
||||
|
||||
class MIHAppDrawer extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
final ImageProvider<Object>? propicFile;
|
||||
|
||||
const MIHAppDrawer({
|
||||
super.key,
|
||||
required this.signedInUser,
|
||||
required this.propicFile,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHAppDrawer> createState() => _MIHAppDrawerState();
|
||||
}
|
||||
|
||||
class _MIHAppDrawerState extends State<MIHAppDrawer> {
|
||||
final proPicController = TextEditingController();
|
||||
late Widget profilePictureLoaded;
|
||||
Future<bool> signOut() async {
|
||||
await SuperTokens.signOut(completionHandler: (error) {
|
||||
// handle error if any
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget displayProPic() {
|
||||
// return MIHProfilePicture(
|
||||
// profilePictureFile: widget.propicFile,
|
||||
// proPicController: proPicController,
|
||||
// proPic: null,
|
||||
// width: 45,
|
||||
// radius: 21,
|
||||
// editable: false,
|
||||
// onChange: (newProPic) {},
|
||||
// ),
|
||||
//print(widget.propicFile);
|
||||
ImageProvider logoFrame =
|
||||
MzanziInnovationHub.of(context)!.theme.logoFrame();
|
||||
if (widget.propicFile != null) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed(
|
||||
'/user-profile',
|
||||
arguments: AppProfileUpdateArguments(
|
||||
widget.signedInUser, widget.propicFile),
|
||||
);
|
||||
},
|
||||
child: MIHProfilePicture(
|
||||
profilePictureFile: widget.propicFile,
|
||||
proPicController: proPicController,
|
||||
proPic: null,
|
||||
width: 60,
|
||||
radius: 27,
|
||||
drawerMode: true,
|
||||
editable: false,
|
||||
onChange: (newProPic) {},
|
||||
),
|
||||
|
||||
// Stack(
|
||||
// alignment: Alignment.center,
|
||||
// fit: StackFit.loose,
|
||||
// children: [
|
||||
// CircleAvatar(
|
||||
// backgroundColor:
|
||||
// MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// backgroundImage: widget.propicFile,
|
||||
// //'https://media.licdn.com/dms/image/D4D03AQGd1-QhjtWWpA/profile-displayphoto-shrink_400_400/0/1671698053061?e=2147483647&v=beta&t=a3dJI5yxs5-KeXjj10LcNCFuC9IOfa8nNn3k_Qyr0CA'),
|
||||
// radius: 27,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 60,
|
||||
// child: Image(image: logoFrame),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
);
|
||||
} else {
|
||||
return SizedBox(
|
||||
width: 60,
|
||||
child: Image(image: logoFrame),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
proPicController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
setState(() {
|
||||
profilePictureLoaded = displayProPic();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// precacheImage(
|
||||
// MzanziInnovationHub.of(context)!.theme.logoImage().image, context);
|
||||
ImageProvider logoThemeSwitch =
|
||||
MzanziInnovationHub.of(context)!.theme.logoImage();
|
||||
return Drawer(
|
||||
//backgroundColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
child: Stack(children: [
|
||||
ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
DrawerHeader(
|
||||
decoration: BoxDecoration(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: 400,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
profilePictureLoaded,
|
||||
Text(
|
||||
"${widget.signedInUser.fname} ${widget.signedInUser.lname}",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"@${widget.signedInUser.username}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
widget.signedInUser.type.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.primaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.home_outlined,
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
const SizedBox(width: 25.0),
|
||||
Text(
|
||||
"Home",
|
||||
style: TextStyle(
|
||||
//fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil('/', (route) => false);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.logout,
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
const SizedBox(width: 25.0),
|
||||
Text(
|
||||
"Sign Out",
|
||||
style: TextStyle(
|
||||
//fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () async {
|
||||
await SuperTokens.signOut(completionHandler: (error) {
|
||||
//print(error);
|
||||
});
|
||||
if (await SuperTokens.doesSessionExist() == false) {
|
||||
Navigator.of(context).popAndPushNamed('/');
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 5,
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (MzanziInnovationHub.of(context)?.theme.mode == "Dark") {
|
||||
//darkm = !darkm;
|
||||
MzanziInnovationHub.of(context)!.changeTheme(ThemeMode.light);
|
||||
//print("Dark Mode: $darkm");
|
||||
} else {
|
||||
//darkm = !darkm;
|
||||
MzanziInnovationHub.of(context)!.changeTheme(ThemeMode.dark);
|
||||
//print("Dark Mode: $darkm");
|
||||
}
|
||||
Navigator.of(context).popAndPushNamed('/');
|
||||
});
|
||||
},
|
||||
child: Image(image: logoThemeSwitch),
|
||||
),
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// if (MzanziInnovationHub.of(context)?.theme.mode == "Dark") {
|
||||
// //darkm = !darkm;
|
||||
// MzanziInnovationHub.of(context)!.changeTheme(ThemeMode.light);
|
||||
// //print("Dark Mode: $darkm");
|
||||
// } else {
|
||||
// //darkm = !darkm;
|
||||
// MzanziInnovationHub.of(context)!.changeTheme(ThemeMode.dark);
|
||||
// //print("Dark Mode: $darkm");
|
||||
// }
|
||||
// Navigator.of(context).popAndPushNamed('/');
|
||||
// });
|
||||
// },
|
||||
// icon: Icon(
|
||||
// Icons.light_mode,
|
||||
// color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
103
Frontend/lib/mih_components/mih_layout/mih_body.dart
Normal file
103
Frontend/lib/mih_components/mih_layout/mih_body.dart
Normal file
@@ -0,0 +1,103 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHBody extends StatefulWidget {
|
||||
final bool borderOn;
|
||||
final List<Widget> bodyItems;
|
||||
const MIHBody({
|
||||
super.key,
|
||||
required this.borderOn,
|
||||
required this.bodyItems,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHBody> createState() => _MIHBodyState();
|
||||
}
|
||||
|
||||
class _MIHBodyState extends State<MIHBody> {
|
||||
//double paddingSize = 10;
|
||||
|
||||
double getHorizontalPaddingSize(Size screenSize) {
|
||||
if (MzanziInnovationHub.of(context)!.theme.screenType == "desktop") {
|
||||
if (widget.borderOn) {
|
||||
return 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// mobile
|
||||
if (widget.borderOn) {
|
||||
return 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double getVerticalPaddingSize(Size screenSize) {
|
||||
// mobile
|
||||
if (widget.borderOn) {
|
||||
return 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Decoration? getBoader() {
|
||||
if (widget.borderOn) {
|
||||
return BoxDecoration(
|
||||
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
borderRadius: BorderRadius.circular(25.0),
|
||||
border: Border.all(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 3.0),
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size screenSize = MediaQuery.sizeOf(context);
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getHorizontalPaddingSize(screenSize),
|
||||
right: getHorizontalPaddingSize(screenSize),
|
||||
bottom: getVerticalPaddingSize(screenSize),
|
||||
top: 0,
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10,
|
||||
right: 10,
|
||||
bottom: 10,
|
||||
top: getVerticalPaddingSize(screenSize),
|
||||
),
|
||||
width: screenSize.width,
|
||||
height: screenSize.height,
|
||||
decoration: getBoader(),
|
||||
child: ScrollConfiguration(
|
||||
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: widget.bodyItems,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
39
Frontend/lib/mih_components/mih_layout/mih_header.dart
Normal file
39
Frontend/lib/mih_components/mih_layout/mih_header.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MIHHeader extends StatefulWidget {
|
||||
final MainAxisAlignment headerAlignment;
|
||||
final List<Widget> headerItems;
|
||||
const MIHHeader({
|
||||
super.key,
|
||||
required this.headerAlignment,
|
||||
required this.headerItems,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHHeader> createState() => _MIHHeaderState();
|
||||
}
|
||||
|
||||
class _MIHHeaderState extends State<MIHHeader> {
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 50,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: widget.headerAlignment,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: widget.headerItems,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
150
Frontend/lib/mih_components/mih_layout/mih_layout_builder.dart
Normal file
150
Frontend/lib/mih_components/mih_layout/mih_layout_builder.dart
Normal file
@@ -0,0 +1,150 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/mih_components/mih_layout/mih_app_drawer.dart';
|
||||
|
||||
import 'mih_body.dart';
|
||||
import 'mih_header.dart';
|
||||
|
||||
class MIHLayoutBuilder extends StatefulWidget {
|
||||
final Widget actionButton;
|
||||
final Widget? secondaryActionButton;
|
||||
final MIHHeader header;
|
||||
final MIHBody body;
|
||||
final MIHAppDrawer? actionDrawer;
|
||||
final Widget? secondaryActionDrawer;
|
||||
final Widget? bottomNavBar;
|
||||
final bool pullDownToRefresh;
|
||||
final Future<void> Function() onPullDown;
|
||||
//final String type;
|
||||
const MIHLayoutBuilder({
|
||||
super.key,
|
||||
required this.actionButton,
|
||||
required this.header,
|
||||
required this.secondaryActionButton,
|
||||
required this.body,
|
||||
required this.actionDrawer,
|
||||
required this.secondaryActionDrawer,
|
||||
required this.bottomNavBar,
|
||||
required this.pullDownToRefresh,
|
||||
required this.onPullDown,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHLayoutBuilder> createState() => _MIHLayoutBuilderState();
|
||||
}
|
||||
|
||||
class _MIHLayoutBuilderState extends State<MIHLayoutBuilder> {
|
||||
List<Widget> getList() {
|
||||
List<Widget> temp = [];
|
||||
temp.add(widget.header);
|
||||
temp.add(widget.body);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// openTheDrawer() {
|
||||
// _scaffoldKey.currentState!.openEndDrawer();
|
||||
// }
|
||||
|
||||
Widget getLayoutHeader() {
|
||||
List<Widget> temp = [];
|
||||
temp.add(widget.actionButton);
|
||||
temp.add(Flexible(child: widget.header));
|
||||
if (widget.secondaryActionButton != null) {
|
||||
temp.add(widget.secondaryActionButton!);
|
||||
} else {
|
||||
//print(widget.header.headerItems.length);
|
||||
if (widget.header.headerItems.length == 1) {
|
||||
temp.add(const SizedBox(
|
||||
width: 50,
|
||||
));
|
||||
}
|
||||
}
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: temp,
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBody(double width, double height) {
|
||||
if (widget.pullDownToRefresh == true) {
|
||||
return LayoutBuilder(builder: (context, BoxConstraints constraints) {
|
||||
double newheight = constraints.maxHeight;
|
||||
//print(newheight);
|
||||
return RefreshIndicator(
|
||||
onRefresh: widget.onPullDown,
|
||||
child: ListView.builder(
|
||||
itemCount: 1,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return SafeArea(
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: newheight,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 5),
|
||||
getLayoutHeader(),
|
||||
const SizedBox(height: 5),
|
||||
Expanded(child: widget.body),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
// child: SafeArea(
|
||||
// child: SizedBox(
|
||||
// width: width,
|
||||
// height: height,
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// children: [
|
||||
// getLayoutHeader(),
|
||||
// Expanded(child: widget.body),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return SafeArea(
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 5),
|
||||
getLayoutHeader(),
|
||||
const SizedBox(height: 5),
|
||||
Expanded(child: widget.body),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size screenSize = MediaQuery.sizeOf(context);
|
||||
return Scaffold(
|
||||
//drawerEnableOpenDragGesture: true,
|
||||
drawer: widget.actionDrawer,
|
||||
endDrawer: widget.secondaryActionDrawer,
|
||||
body: getBody(screenSize.width, screenSize.height),
|
||||
bottomNavigationBar: widget.bottomNavBar,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
import 'package:supertokens_flutter/http.dart' as http;
|
||||
|
||||
import '../../mih_env/env.dart';
|
||||
import '../../mih_objects/app_user.dart';
|
||||
import '../../mih_objects/notification.dart';
|
||||
import '../mih_pop_up_messages/mih_error_message.dart';
|
||||
|
||||
class MIHNotificationDrawer extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
final List<MIHNotification> notifications;
|
||||
//final ImageProvider<Object>? propicFile;
|
||||
|
||||
const MIHNotificationDrawer({
|
||||
super.key,
|
||||
required this.signedInUser,
|
||||
required this.notifications,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHNotificationDrawer> createState() => _MIHNotificationDrawerState();
|
||||
}
|
||||
|
||||
class _MIHNotificationDrawerState extends State<MIHNotificationDrawer> {
|
||||
late List<List<String>> notificationList;
|
||||
final baseAPI = AppEnviroment.baseApiUrl;
|
||||
Future<void> updateNotificationAPICall(int index) async {
|
||||
var response = await http.put(
|
||||
Uri.parse(
|
||||
"$baseAPI/notifications/update/${widget.notifications[index].idnotifications}"),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed(
|
||||
"/",
|
||||
);
|
||||
Navigator.of(context).pushNamed(
|
||||
widget.notifications[index].action_path,
|
||||
arguments: widget.signedInUser,
|
||||
);
|
||||
} else {
|
||||
internetConnectionPopUp();
|
||||
}
|
||||
}
|
||||
|
||||
void internetConnectionPopUp() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Internet Connection");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<List<String>> setTempNofitications() {
|
||||
List<List<String>> temp = [];
|
||||
temp.add(["Notification 1", "Notification Description 1"]);
|
||||
temp.add(["Notification 2", "Notification Description 2"]);
|
||||
temp.add(["Notification 3", "Notification Description 3"]);
|
||||
temp.add(["Notification 4", "Notification Description 4"]);
|
||||
temp.add(["Notification 5", "Notification Description 5"]);
|
||||
temp.add(["Notification 6", "Notification Description 6"]);
|
||||
temp.add(["Notification 7", "Notification Description 7"]);
|
||||
temp.add(["Notification 8", "Notification Description 8"]);
|
||||
temp.add(["Notification 9", "Notification Description 9"]);
|
||||
temp.add(["Notification 10", "Notification Description 10"]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
Widget displayTempNotifications(int index) {
|
||||
String title = notificationList[index][0];
|
||||
String subtitle = notificationList[index][1];
|
||||
return ListTile(
|
||||
title: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
subtitle,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
onTap: () {},
|
||||
);
|
||||
}
|
||||
|
||||
Widget displayNotifications(int index) {
|
||||
String title = widget.notifications[index].notification_type;
|
||||
String subtitle =
|
||||
"${widget.notifications[index].insert_date}\n${widget.notifications[index].notification_message}";
|
||||
Widget notificationTitle;
|
||||
if (widget.notifications[index].notification_read == "No") {
|
||||
notificationTitle = Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.circle_notifications,
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
notificationTitle = Row(
|
||||
children: [
|
||||
//const Icon(Icons.circle_notifications),
|
||||
Flexible(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
title: notificationTitle,
|
||||
subtitle: Text(
|
||||
subtitle,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (widget.notifications[index].notification_read == "No") {
|
||||
updateNotificationAPICall(index);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(
|
||||
widget.notifications[index].action_path,
|
||||
arguments: widget.signedInUser,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget displayNotification() {
|
||||
if (widget.notifications.isNotEmpty) {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, index) {
|
||||
return Divider(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
);
|
||||
},
|
||||
itemCount: widget.notifications.length,
|
||||
itemBuilder: (context, index) {
|
||||
//final patient = widget.patients[index].id_no.contains(widget.searchString);
|
||||
//print(index);
|
||||
return displayNotifications(index);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.only(top: 35),
|
||||
child: Text(
|
||||
"No Notifications",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
setState(() {
|
||||
notificationList = setTempNofitications();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Drawer(
|
||||
//backgroundColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: Text(
|
||||
"Notifications",
|
||||
style: TextStyle(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
displayNotification(),
|
||||
// ListView.separated(
|
||||
// shrinkWrap: true,
|
||||
// physics: const NeverScrollableScrollPhysics(),
|
||||
// separatorBuilder: (BuildContext context, index) {
|
||||
// return Divider(
|
||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// );
|
||||
// },
|
||||
// itemCount: widget.notifications.length,
|
||||
// itemBuilder: (context, index) {
|
||||
// //final patient = widget.patients[index].id_no.contains(widget.searchString);
|
||||
// //print(index);
|
||||
// return displayNotifications(index);
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
53
Frontend/lib/mih_components/mih_layout/mih_print_prevew.dart
Normal file
53
Frontend/lib/mih_components/mih_layout/mih_print_prevew.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/mih_components/mih_layout/mih_action.dart';
|
||||
import 'package:pdf/pdf.dart';
|
||||
import 'package:printing/printing.dart';
|
||||
|
||||
import '../../mih_objects/arguments.dart';
|
||||
import '../mih_pop_up_messages/mih_loading_circle.dart';
|
||||
|
||||
class MIHPrintPreview extends StatefulWidget {
|
||||
final PrintPreviewArguments arguments;
|
||||
const MIHPrintPreview({
|
||||
super.key,
|
||||
required this.arguments,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHPrintPreview> createState() => _MIHPrintPreviewState();
|
||||
}
|
||||
|
||||
class _MIHPrintPreviewState extends State<MIHPrintPreview> {
|
||||
MIHAction getActionButton() {
|
||||
return MIHAction(
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
),
|
||||
iconSize: 35,
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PdfPreview(
|
||||
pdfFileName: widget.arguments.fileName,
|
||||
initialPageFormat: PdfPageFormat.a4,
|
||||
loadingWidget: const Mihloadingcircle(),
|
||||
actions: [getActionButton()],
|
||||
build: (format) => widget.arguments.pdfData,
|
||||
);
|
||||
}
|
||||
}
|
||||
185
Frontend/lib/mih_components/mih_layout/mih_tile.dart
Normal file
185
Frontend/lib/mih_components/mih_layout/mih_tile.dart
Normal file
@@ -0,0 +1,185 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../../main.dart';
|
||||
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
||||
|
||||
import 'mih_window.dart';
|
||||
|
||||
class MIHTile extends StatefulWidget {
|
||||
final String tileName;
|
||||
final String? videoYTLink;
|
||||
final Widget tileIcon;
|
||||
final void Function() onTap;
|
||||
// final Widget tileIcon;
|
||||
final Color p;
|
||||
final Color s;
|
||||
|
||||
const MIHTile({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
required this.tileName,
|
||||
this.videoYTLink,
|
||||
required this.tileIcon,
|
||||
required this.p,
|
||||
required this.s,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHTile> createState() => _MIHTileState();
|
||||
}
|
||||
|
||||
class _MIHTileState extends State<MIHTile> {
|
||||
late Color mainC;
|
||||
late Color secondC;
|
||||
late YoutubePlayerController videoController;
|
||||
|
||||
String getVideID() {
|
||||
if (widget.videoYTLink != null) {
|
||||
return YoutubePlayer.convertUrlToId(widget.videoYTLink!) as String;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// void listener() {
|
||||
// if (_isPlayerReady && mounted && !videoController.value.isFullScreen) {
|
||||
// setState(() {
|
||||
// _playerState = videoController.value.playerState;
|
||||
// _videoMetaData = videoController.metadata;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
videoController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
mainC = widget.p;
|
||||
secondC = widget.s;
|
||||
|
||||
videoController = YoutubePlayerController(
|
||||
initialVideoId: getVideID(),
|
||||
flags: YoutubePlayerFlags(
|
||||
autoPlay: false,
|
||||
mute: true,
|
||||
isLive: false,
|
||||
));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void displayHint() {
|
||||
if (widget.videoYTLink != null) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MIHWindow(
|
||||
fullscreen: false,
|
||||
windowTitle: widget.tileName,
|
||||
windowTools: const [],
|
||||
onWindowTapClose: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
windowBody: [
|
||||
YoutubePlayerBuilder(
|
||||
player: YoutubePlayer(
|
||||
controller: videoController,
|
||||
showVideoProgressIndicator: true,
|
||||
progressIndicatorColor: Colors.amber,
|
||||
progressColors: ProgressBarColors(
|
||||
playedColor: Colors.amber,
|
||||
handleColor: Colors.amberAccent,
|
||||
),
|
||||
),
|
||||
builder: (context, player) {
|
||||
return player;
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// print(
|
||||
// "Tile Name: ${widget.tileName}\nTitle Type: ${widget.tileIcon.runtimeType.toString()}");
|
||||
return FittedBox(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
AnimatedContainer(
|
||||
//alignment: Alignment.center,
|
||||
width: 250,
|
||||
height: 250,
|
||||
duration: const Duration(seconds: 2),
|
||||
child: Material(
|
||||
color: mainC,
|
||||
// shadowColor:
|
||||
// MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// elevation: 5,
|
||||
borderRadius: BorderRadius.circular(80),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(80),
|
||||
// ho
|
||||
onTap: widget.onTap,
|
||||
onLongPress: () {
|
||||
displayHint();
|
||||
},
|
||||
// hoverDuration: ,
|
||||
splashColor:
|
||||
MzanziInnovationHub.of(context)!.theme.highlightColor(),
|
||||
highlightColor:
|
||||
MzanziInnovationHub.of(context)!.theme.highlightColor(),
|
||||
child: widget.tileIcon,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Material(
|
||||
// color: mainC,
|
||||
// borderRadius: BorderRadius.circular(80),
|
||||
// child: Ink(
|
||||
// // width: 200,
|
||||
// // height: 200,
|
||||
// padding: const EdgeInsets.all(20),
|
||||
// child: InkWell(
|
||||
// onTap: widget.onTap,
|
||||
// hoverDuration: Duration(seconds: 2),
|
||||
// highlightColor:
|
||||
// MzanziInnovationHub.of(context)!.theme.messageTextColor(),
|
||||
// child: SizedBox(
|
||||
// height: 200,
|
||||
// width: 200,
|
||||
// child: widget.tileIcon,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: Text(
|
||||
widget.tileName,
|
||||
textAlign: TextAlign.center,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.visible,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
fontSize: 40.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
214
Frontend/lib/mih_components/mih_layout/mih_window.dart
Normal file
214
Frontend/lib/mih_components/mih_layout/mih_window.dart
Normal file
@@ -0,0 +1,214 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../main.dart';
|
||||
|
||||
class MIHWindow extends StatefulWidget {
|
||||
final String windowTitle;
|
||||
final List<Widget> windowBody;
|
||||
final List<Widget> windowTools;
|
||||
final void Function() onWindowTapClose;
|
||||
final bool fullscreen;
|
||||
const MIHWindow({
|
||||
super.key,
|
||||
required this.fullscreen,
|
||||
required this.windowTitle,
|
||||
required this.windowTools,
|
||||
required this.onWindowTapClose,
|
||||
required this.windowBody,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MIHWindow> createState() => _MIHWindowState();
|
||||
}
|
||||
|
||||
class _MIHWindowState extends State<MIHWindow> {
|
||||
late double windowTitleSize;
|
||||
late double horizontralWindowPadding;
|
||||
late double vertticalWindowPadding;
|
||||
late double windowWidth;
|
||||
late double windowHeight;
|
||||
late double width;
|
||||
late double height;
|
||||
|
||||
void checkScreenSize() {
|
||||
// print("screen width: $width");
|
||||
// print("screen height: $height");
|
||||
if (MzanziInnovationHub.of(context)!.theme.screenType == "desktop") {
|
||||
setState(() {
|
||||
windowTitleSize = 25;
|
||||
horizontralWindowPadding = width / 7;
|
||||
vertticalWindowPadding = 25;
|
||||
windowWidth = width;
|
||||
windowHeight = height;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
windowTitleSize = 20;
|
||||
horizontralWindowPadding = 10;
|
||||
vertticalWindowPadding = 10;
|
||||
windowWidth = width;
|
||||
windowHeight = height;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget getWidnowClose() {
|
||||
return Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: IconButton(
|
||||
onPressed: widget.onWindowTapClose,
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getWidnowTools() {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: widget.windowTools,
|
||||
);
|
||||
}
|
||||
|
||||
Widget getWidnowTitle() {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.windowTitle,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
fontSize: windowTitleSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget getWidnowHeader() {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
getWidnowTools(),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: getWidnowTitle(),
|
||||
),
|
||||
getWidnowClose(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget getWidnowBody() {
|
||||
if (widget.fullscreen) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: widget.windowBody,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: widget.windowBody,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget createWindow(Widget header, Widget body) {
|
||||
Widget visibleItems;
|
||||
if (widget.fullscreen) {
|
||||
visibleItems = Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
header,
|
||||
//const Divider(),
|
||||
body,
|
||||
],
|
||||
);
|
||||
} else {
|
||||
visibleItems = SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
header,
|
||||
//const Divider(),
|
||||
body,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return Dialog(
|
||||
insetPadding: EdgeInsets.symmetric(
|
||||
horizontal: horizontralWindowPadding,
|
||||
vertical: vertticalWindowPadding,
|
||||
),
|
||||
insetAnimationCurve: Easing.emphasizedDecelerate,
|
||||
insetAnimationDuration: Durations.short1,
|
||||
child: Container(
|
||||
//padding: const EdgeInsets.all(10),
|
||||
width: windowWidth,
|
||||
//height: windowHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
borderRadius: BorderRadius.circular(25.0),
|
||||
border: Border.all(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
width: 5.0),
|
||||
),
|
||||
child: visibleItems,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var size = MediaQuery.of(context).size;
|
||||
setState(() {
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
});
|
||||
checkScreenSize();
|
||||
return createWindow(
|
||||
getWidnowHeader(),
|
||||
getWidnowBody(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user