fist commit ftc staff app clone

This commit is contained in:
2024-08-01 13:46:46 +05:30
commit bf9064a9c9
515 changed files with 42796 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/models/clients/HealthIssuesDetailsModel.dart';
import 'package:ftc_mobile_app/models/profileData/user_data.dart';
import 'package:ftc_mobile_app/utilities/enums/body_parts.dart';
import 'package:ftc_mobile_app/view/custom_widgets/custom_app_bar_with_action.dart';
import 'package:ftc_mobile_app/view/custom_widgets/human_body_mapper_widget.dart';
import 'package:ftc_mobile_app/view/custom_widgets/my_circle_image.dart';
import 'package:get/get.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import '../add_details_to_new_body_point_screen.dart';
import 'widget/IssueDetailPopupWidget.dart';
class CurrentHealthIssuesScreen extends StatefulWidget {
final UserData userData;
const CurrentHealthIssuesScreen({Key? key, required this.userData})
: super(key: key);
@override
State<CurrentHealthIssuesScreen> createState() =>
_CurrentHealthIssuesScreenState();
}
class _CurrentHealthIssuesScreenState extends State<CurrentHealthIssuesScreen> {
final CurrentHealthIssuesScreenController controller =
Get.put(CurrentHealthIssuesScreenController());
@override
void initState() {
controller.serviceUserId = widget.userData.id!;
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: controller.tabs.length,
child: CustomScaffold(
backgroundColor: CustomAppColors.kPrimaryColor,
onBackButton: () => controller.onBackPress(context),
screenKey: controller.screenKey,
onScreenTap: controller.removeFocus,
sideDrawer: const CustomDrawer(),
showAppBar: true,
appBar: _appBar(context),
body: SingleChildScrollView(
child: Column(
children: [
//User details
serviceUserDetailWidget(),
Divider(
height: 1,
color: CustomAppColors.kLightGreyColor,
),
TabBar(
onTap: (i) {
controller.onTabChange(controller.tabs[i]);
},
tabs: controller.tabs
.map((e) => Tab(
text: e,
))
.toList()),
Divider(
height: 1,
color: CustomAppColors.kLightGreyColor,
),
8.verticalSpace,
Obx(() {
final entries = controller.issueBodyParts.entries;
if (entries.isEmpty) {
return FrequentFunctions.noWidget;
}
final map = <BodyPart, Color?>{};
for (var e in entries) {
map[e.key] = e.value.color;
}
return HumanBodyWidget(
visibleBodyPoints: map,
width: Get.width * 0.9,
onPointTap: (b, p) {
RenderBox? overlay = Overlay.of(context)
.context
.findRenderObject() as RenderBox?;
showMenu(
context: context,
surfaceTintColor: Colors.white,
position: RelativeRect.fromRect(
p & const Size(40, 40),
// Smaller rect, the touch area
Offset.zero &
(overlay?.size ??
Get.mediaQuery
.size), // Bigger rect, the entire screen
),
items: [
PopupMenuItem(
padding: EdgeInsets.zero,
child: IssueDetailPopupWidget(
userData: widget.userData,
data: controller.issueBodyParts[b]!.data,
onActionChange: (status, data) {
if (data.status != status) {
controller.updateHealthIssueStatus(
bodyPoint: b, data: data, status: status);
}
},
onUpdateButtonTap: (data) async {
Get.back();
onAddOrUpdateButtonTap(context, data);
},
),
),
]);
},
);
}),
],
),
),
),
);
}
AppBar _appBar(BuildContext context) {
return CustomAppBarWithAction(
context,
titleText: "Current Health Issues",
actionText: '+ Add New',
onActionTap: () => onAddOrUpdateButtonTap(context),
);
}
Widget serviceUserDetailWidget() {
return Padding(
padding: REdgeInsets.symmetric(horizontal: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.center,
child: MyCircleImage(
imageSize: 80.r,
url:
"${WebUrls.baseUrl}${widget.userData.profilePictureUrl ?? ""}",
errorWidget: CustomImageWidget(
imagePath: AssetsManager.kPersonMainIcon,
height: 53.r,
width: 53.r,
),
),
),
10.verticalSpace,
CustomTextWidget(
text: widget.userData.displayName,
fontSize: 14.sp,
fontWeight: FontWeight.w600),
32.verticalSpace,
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _labelValueWidgets(
'Email:',
widget.userData.email ?? "",
),
)),
8.horizontalSpace,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _labelValueWidgets(
'Contact Number:',
widget.userData.modelId?.phoneNo ?? "",
),
)),
],
),
16.verticalSpace,
..._labelValueWidgets(
'Address 1:',
widget.userData.modelId?.suAddress1 ?? "",
),
16.verticalSpace,
..._labelValueWidgets(
'Address 2:',
widget.userData.modelId?.suAddress2 ?? "",
),
16.verticalSpace,
],
),
);
}
List<Widget> _labelValueWidgets(String label, String value) {
return [
CustomTextWidget(
textAlign: TextAlign.left,
isExpanded: false,
text: label,
fontWeight: FontWeight.w600,
fontColor: CustomAppColors.kLightTextColor,
fontSize: 12.sp),
4.verticalSpace,
CustomTextWidget(
textAlign: TextAlign.left,
text: value,
isExpanded: false,
fontWeight: FontWeight.w400,
fontColor: CustomAppColors.kBlackColor,
fontSize: 13.sp),
];
}
Future<void> onAddOrUpdateButtonTap(BuildContext context,
[HealthIssueDetailsModel? data]) async {
dynamic result = await Navigator.of(context)
.pushNamed(CustomRouteNames.kAddDetailsToNewPointScreenRoute,
arguments: AddDetailsToNewBodyPointScreenArgs(
userData: widget.userData,
issueData: data,
));
if (result == true) {
controller.getPointsDataFromService();
}
}
}

View File

@@ -0,0 +1,260 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/models/clients/HealthIssuesDetailsModel.dart';
import 'package:ftc_mobile_app/models/profileData/user_data.dart';
import 'package:ftc_mobile_app/utilities/extensions/custom_extensions.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
class IssueDetailPopupWidget extends StatefulWidget {
const IssueDetailPopupWidget({
super.key,
required this.userData,
required this.data,
required this.onActionChange,
required this.onUpdateButtonTap,
});
final UserData userData;
final HealthIssueDetailsModel data;
final Function(bool status, HealthIssueDetailsModel data) onActionChange;
final Function(HealthIssueDetailsModel data) onUpdateButtonTap;
static const actionActive = "Active";
static const actionResolved = "Resolved";
@override
State<IssueDetailPopupWidget> createState() => _IssueDetailPopupWidgetState();
}
class _IssueDetailPopupWidgetState extends State<IssueDetailPopupWidget> {
final Map<String, bool> actionsMap = {
IssueDetailPopupWidget.actionActive: true,
IssueDetailPopupWidget.actionResolved: false
};
String selectedValue = IssueDetailPopupWidget.actionActive;
@override
void initState() {
selectedValue = widget.data.status
? IssueDetailPopupWidget.actionActive
: IssueDetailPopupWidget.actionResolved;
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: Get.width,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.maxFinite,
padding: REdgeInsets.symmetric(horizontal: 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Health Note',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
),
CustomTextWidget(
text: widget.data.healthNote,
fontSize: 14.sp,
fontWeight: FontWeight.bold,
textAlign: TextAlign.left,
isExpanded: false),
],
),
),
Container(
width: 90.r,
height: 32.r,
decoration: BoxDecoration(
borderRadius: 24.toRadius(),
color: (selectedValue ==
IssueDetailPopupWidget.actionActive)
? Colors.red.withOpacity(0.3)
: Colors.green.withOpacity(0.3),
),
child: DropdownButtonHideUnderline(
child: DropdownButtonFormField(
onTap: () {
FocusScopeNode().unfocus();
},
value: selectedValue,
dropdownColor: Colors.white,
borderRadius: 4.toRadius(),
decoration: InputDecoration(
isDense: true,
border: InputBorder.none,
suffixIcon: Icon(Icons.arrow_drop_down_sharp,
size: 18,
color: (selectedValue ==
IssueDetailPopupWidget.actionActive)
? Colors.red
: Colors.green)
.paddingOnly(right: 12.r),
suffixIconConstraints: BoxConstraints.tightFor(
width: 24.r, height: 32.r),
// contentPadding: REdgeInsets.only(left: 0),
),
elevation: 4,
icon: FrequentFunctions.noWidget,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 10.sp,
color: Colors.black),
hint: Text(
"Select...",
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 12.sp,
color: CustomAppColors.kLightTextColor,
),
),
selectedItemBuilder: (_) {
return actionsMap.keys.map(
(e) {
return DropdownMenuItem<String>(
value: e,
child: Container(
// color: (selectedValue == e)
// ? (selectedValue ==
// IssueDetailPopupWidget
// .actionActive)
// ? Colors.red.withOpacity(0.3)
// : Colors.green.withOpacity(0.3)
// : Colors.white,
alignment: Alignment.center,
child: Text(
e,
style: TextStyle(
color: (selectedValue == e)
? (selectedValue ==
IssueDetailPopupWidget
.actionActive)
? Colors.red
: Colors.green
: Colors.black),
),
),
);
},
).toList();
},
items: actionsMap.keys
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(e),
),
)
.toList(),
// padding: EdgeInsets.zero,
isExpanded: true,
// iconSize: 20.h,
// icon: Padding(
// padding: REdgeInsets.only(right: 0.0),
// child: Icon(Icons.arrow_drop_down_sharp,
// size: 18,
// color: Colors.black),
// ),
onChanged: (v) {
if (v != null) {
setState(() {
selectedValue = v;
widget.onActionChange(
actionsMap[v]!, widget.data);
});
}
},
),
),
)
],
),
),
8.verticalSpace,
Divider(
height: 1,
color: Colors.grey.withOpacity(0.3),
),
Container(
width: double.maxFinite,
padding: REdgeInsets.symmetric(horizontal: 12, vertical: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text.rich(
textAlign: TextAlign.left,
TextSpan(
children: [
TextSpan(
text: "Complaint: ",
style: TextStyle(
fontSize: 12.sp, fontWeight: FontWeight.w600),
),
TextSpan(
text: widget.data.complaint,
style: TextStyle(
fontSize: 12.sp, fontWeight: FontWeight.w400),
),
],
),
),
4.verticalSpace,
Text.rich(
textAlign: TextAlign.left,
TextSpan(
children: [
TextSpan(
text: "Last Update: ",
style: TextStyle(
fontSize: 12.sp, fontWeight: FontWeight.w600),
),
TextSpan(
text: DateFormat("MMM/dd/yyyy").format(
DateTime.parse(widget.data.updatedAt)
.toLocal()),
style: TextStyle(
fontSize: 12.sp, fontWeight: FontWeight.w400),
),
],
),
),
],
),
),
16.verticalSpace,
Center(
child: SizedBox(
width: 120.r,
height: 32.r,
child: CustomAppButton(
onTap: () => widget.onUpdateButtonTap(widget.data),
buttonText: "Update",
),
),
),
],
),
),
],
);
}
}