gas refill comments
parent
6b740549a5
commit
d3bee4f39a
@ -0,0 +1,112 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:test_sa/controllers/api_routes/api_manager.dart';
|
||||||
|
import 'package:test_sa/controllers/api_routes/urls.dart';
|
||||||
|
import 'package:test_sa/extensions/context_extension.dart';
|
||||||
|
|
||||||
|
import '../../../models/gas_refill_comments_model.dart';
|
||||||
|
import '../../../new_views/common_widgets/app_lazy_loading.dart';
|
||||||
|
|
||||||
|
class GasRefillCommentsProvider extends ChangeNotifier {
|
||||||
|
// number of items call in each request
|
||||||
|
final pageItemNumber = 12;
|
||||||
|
|
||||||
|
//reset provider data
|
||||||
|
void reset() {
|
||||||
|
comments = [];
|
||||||
|
nextPage = true;
|
||||||
|
stateCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state code of current request to defied error message
|
||||||
|
// like 400 customer request failed
|
||||||
|
// 500 service not available
|
||||||
|
int stateCode;
|
||||||
|
|
||||||
|
// true if there is next page in product list and false if not
|
||||||
|
bool nextPage = true;
|
||||||
|
|
||||||
|
// list of user requests
|
||||||
|
List<GasRefillComment> comments = [];
|
||||||
|
|
||||||
|
// when requests in-process _loading = true
|
||||||
|
// done _loading = true
|
||||||
|
// failed _loading = false
|
||||||
|
bool isLoading;
|
||||||
|
|
||||||
|
/// return -2 if request in progress
|
||||||
|
/// return -1 if error happen when sending request
|
||||||
|
/// return state code if request complete may be 200, 404 or 403
|
||||||
|
/// for more details check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> getComments({@required String callId}) async {
|
||||||
|
if (isLoading == true) return -2;
|
||||||
|
isLoading = true;
|
||||||
|
notifyListeners();
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await ApiManager.instance.get(URLs.getGazRefillComments + "?callRequestId=$callId");
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
List requestsListJson = json.decode(response.body)["data"];
|
||||||
|
List<GasRefillComment> commentsPage = requestsListJson.map((request) => GasRefillComment.fromJson(request)).toList();
|
||||||
|
comments ??= [];
|
||||||
|
comments.addAll(commentsPage);
|
||||||
|
if (commentsPage.length == pageItemNumber) {
|
||||||
|
nextPage = true;
|
||||||
|
} else {
|
||||||
|
nextPage = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
print(error);
|
||||||
|
isLoading = false;
|
||||||
|
stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return -2 if request in progress
|
||||||
|
/// return -1 if error happen when sending request
|
||||||
|
/// return state code if request complete may be 200, 404 or 403
|
||||||
|
/// for more details check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> addComment(BuildContext context, {@required GasRefillComment comment}) async {
|
||||||
|
if (isLoading == true) return -2;
|
||||||
|
isLoading = true;
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
comment.id = 0;
|
||||||
|
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
||||||
|
response = await ApiManager.instance.post(URLs.addGazRefillComment, body: comment.toJson());
|
||||||
|
|
||||||
|
stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
reset(); //visit.status = pentry.ppmVisitStatus;
|
||||||
|
notifyListeners();
|
||||||
|
Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
} else {
|
||||||
|
Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}");
|
||||||
|
}
|
||||||
|
isLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
print(error);
|
||||||
|
isLoading = false;
|
||||||
|
stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
class GasRefillComment {
|
||||||
|
GasRefillComment({
|
||||||
|
this.id,
|
||||||
|
this.gasRefillId,
|
||||||
|
this.createdOn,
|
||||||
|
this.createdBy,
|
||||||
|
this.comment,
|
||||||
|
});
|
||||||
|
|
||||||
|
GasRefillComment.fromJson(dynamic json) {
|
||||||
|
id = json['id'];
|
||||||
|
gasRefillId = json['gasRefillId'];
|
||||||
|
createdOn = json['createdOn'];
|
||||||
|
createdBy = json['createdBy'] != null ? CreatedBy.fromJson(json['createdBy']) : null;
|
||||||
|
comment = json['comment'];
|
||||||
|
}
|
||||||
|
|
||||||
|
num id;
|
||||||
|
num gasRefillId;
|
||||||
|
String createdOn;
|
||||||
|
CreatedBy createdBy;
|
||||||
|
String comment;
|
||||||
|
|
||||||
|
GasRefillComment copyWith({
|
||||||
|
num id,
|
||||||
|
num callRequestId,
|
||||||
|
String createdOn,
|
||||||
|
CreatedBy createdBy,
|
||||||
|
String comment,
|
||||||
|
}) =>
|
||||||
|
GasRefillComment(
|
||||||
|
id: id ?? this.id,
|
||||||
|
gasRefillId: callRequestId ?? this.gasRefillId,
|
||||||
|
createdOn: createdOn ?? this.createdOn,
|
||||||
|
createdBy: createdBy ?? this.createdBy,
|
||||||
|
comment: comment ?? this.comment,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
map['id'] = id;
|
||||||
|
map['gasRefillId'] = gasRefillId;
|
||||||
|
map['createdOn'] = createdOn;
|
||||||
|
if (createdBy != null) {
|
||||||
|
map['createdBy'] = createdBy.toJson();
|
||||||
|
}
|
||||||
|
map['comment'] = comment;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreatedBy {
|
||||||
|
CreatedBy({
|
||||||
|
this.userId,
|
||||||
|
this.userName,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreatedBy.fromJson(dynamic json) {
|
||||||
|
userId = json['userId'];
|
||||||
|
userName = json['userName'];
|
||||||
|
}
|
||||||
|
|
||||||
|
String userId;
|
||||||
|
String userName;
|
||||||
|
|
||||||
|
CreatedBy copyWith({
|
||||||
|
String userId,
|
||||||
|
String userName,
|
||||||
|
}) =>
|
||||||
|
CreatedBy(
|
||||||
|
userId: userId ?? this.userId,
|
||||||
|
userName: userName ?? this.userName,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
map['userId'] = userId;
|
||||||
|
map['userName'] = userName;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:test_sa/controllers/providers/api/gas_refill_comments.dart';
|
||||||
|
import 'package:test_sa/controllers/providers/api/user_provider.dart';
|
||||||
|
import 'package:test_sa/controllers/validator/validator.dart';
|
||||||
|
import 'package:test_sa/extensions/context_extension.dart';
|
||||||
|
import 'package:test_sa/extensions/int_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/string_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/text_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||||
|
import 'package:test_sa/models/enums/user_types.dart';
|
||||||
|
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
|
||||||
|
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
||||||
|
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
|
||||||
|
|
||||||
|
import '../../../../models/gas_refill_comments_model.dart';
|
||||||
|
import '../../../../new_views/app_style/app_color.dart';
|
||||||
|
import '../../../widgets/loaders/loading_manager.dart';
|
||||||
|
|
||||||
|
class GasRefillCommentsBottomSheet extends StatefulWidget {
|
||||||
|
final String requestId;
|
||||||
|
|
||||||
|
const GasRefillCommentsBottomSheet({Key key, @required this.requestId}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<GasRefillCommentsBottomSheet> createState() => _GasRefillCommentsBottomSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GasRefillCommentsBottomSheetState extends State<GasRefillCommentsBottomSheet> {
|
||||||
|
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||||
|
String text;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final commentsProvider = Provider.of<GasRefillCommentsProvider>(context);
|
||||||
|
final userProvider = Provider.of<UserProvider>(context, listen: false);
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Wrap(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
LoadingManager(
|
||||||
|
isLoading: commentsProvider.isLoading,
|
||||||
|
isFailedLoading: commentsProvider.comments == null,
|
||||||
|
stateCode: commentsProvider.stateCode,
|
||||||
|
onRefresh: () async {
|
||||||
|
commentsProvider.reset();
|
||||||
|
await commentsProvider.getComments(callId: widget.requestId);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 40.toScreenWidth,
|
||||||
|
height: 5.toScreenHeight,
|
||||||
|
decoration: BoxDecoration(color: AppColor.neutral40, borderRadius: BorderRadius.circular(30)),
|
||||||
|
),
|
||||||
|
16.height,
|
||||||
|
Align(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: context.translation.comments.heading3(context).custom(fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
commentsProvider.comments.isEmpty
|
||||||
|
? SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.25,
|
||||||
|
child: NoItemFound(message: context.translation.noDataFound),
|
||||||
|
)
|
||||||
|
: LazyLoading(
|
||||||
|
nextPage: commentsProvider.nextPage,
|
||||||
|
onLazyLoad: () async => await commentsProvider.getComments(callId: widget.requestId),
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: commentsProvider.comments.length,
|
||||||
|
padding: const EdgeInsets.only(top: 16, bottom: 8),
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
separatorBuilder: (cxt, index) => 8.height,
|
||||||
|
itemBuilder: (context, itemIndex) {
|
||||||
|
final model = commentsProvider.comments[itemIndex];
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
(model?.createdBy?.userName ?? "Nurse").heading6(context),
|
||||||
|
8.height,
|
||||||
|
(model?.comment ?? "").bodyText(context),
|
||||||
|
8.height,
|
||||||
|
Align(
|
||||||
|
alignment: AlignmentDirectional.bottomEnd,
|
||||||
|
child: Text(DateTime.tryParse(model.createdOn).toIso8601String().toServiceRequestDetailsFormat,
|
||||||
|
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).toShadowContainer(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (userProvider.user.type == UsersTypes.normal_user) 8.height,
|
||||||
|
if (userProvider.user.type == UsersTypes.normal_user)
|
||||||
|
AppTextFormField(
|
||||||
|
labelText: "Type any comment",
|
||||||
|
backgroundColor: AppColor.neutral30,
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
showShadow: false,
|
||||||
|
validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredField,
|
||||||
|
textInputType: TextInputType.multiline,
|
||||||
|
suffixIcon: "comment_send".toSvgAsset().paddingOnly(end: 16).onPress(() {
|
||||||
|
if (_formKey.currentState.validate()) {
|
||||||
|
_formKey.currentState.save();
|
||||||
|
final comment = GasRefillComment(id: 0, gasRefillId: num.tryParse(widget.requestId ?? ""), comment: text);
|
||||||
|
commentsProvider.addComment(context, comment: comment);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
onSaved: (value) {
|
||||||
|
text = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
16.height,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue