Skip to content

Commit e57147a

Browse files
authored
Merge pull request #282 from mdgspace/casper/feedback
feat: integrates feedback with the backend
2 parents 19bc848 + 5e9f2ca commit e57147a

File tree

10 files changed

+275
-193
lines changed

10 files changed

+275
-193
lines changed

lib/data/services/remote/api_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ abstract class ApiService {
5454
Future<List<FeedbackResponse>> responseOfFeedbacks();
5555

5656
@POST(ApiEndpoints.newFeedback)
57-
Future<AppetizerFeedback> newFeedback(
57+
Future<void> newFeedback(
5858
@Body() Map<String, dynamic> map,
5959
);
6060

lib/domain/models/feedback/appetizer_feedback.dart

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,18 @@ part 'appetizer_feedback.g.dart';
44

55
@JsonSerializable(fieldRename: FieldRename.snake)
66
class AppetizerFeedback {
7-
int id;
8-
String type;
97
String title;
108
String message;
11-
int timestamp;
129
dynamic mealId;
13-
dynamic imageUrl;
14-
int dateIssue;
15-
dynamic response;
10+
// dynamic imageUrl;
11+
int ratings;
1612

1713
AppetizerFeedback({
18-
required this.id,
19-
required this.type,
2014
required this.title,
2115
required this.message,
22-
required this.timestamp,
2316
required this.mealId,
24-
required this.imageUrl,
25-
required this.dateIssue,
26-
required this.response,
17+
// required this.imageUrl,
18+
required this.ratings,
2719
});
2820

2921
factory AppetizerFeedback.fromJson(Map<String, dynamic> json) =>

lib/domain/repositories/feedback_repository.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ class FeedbackRepository {
2828
}
2929
}
3030

31-
Future<AppetizerFeedback> newFeedback(AppetizerFeedback feedback) async {
31+
Future<void> newFeedback(AppetizerFeedback feedback) async {
3232
Map<String, dynamic> map = {
33-
'type': feedback.type,
3433
'title': feedback.title,
3534
'message': feedback.message,
36-
'date_issue': feedback.dateIssue,
35+
'meal_id': feedback.mealId,
36+
'ratings': feedback.ratings,
37+
// 'image_url': feedback.imageUrl,
3738
};
3839
try {
39-
return await _apiService.newFeedback(map);
40+
await _apiService.newFeedback(map);
4041
} catch (e) {
4142
debugPrint(e.toString());
4243
throw Failure(AppConstants.GENERIC_FAILURE);

lib/presentation/feedback/bloc/feedback_page_bloc.dart

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:appetizer/domain/models/feedback/appetizer_feedback.dart';
12
import 'package:appetizer/domain/repositories/feedback_repository.dart';
23
import 'package:bloc/bloc.dart';
34
import 'package:equatable/equatable.dart';
@@ -10,36 +11,44 @@ class FeedbackPageBloc extends Bloc<FeedbackPageEvent, FeedbackPageState> {
1011
FeedbackPageBloc({
1112
required this.repo,
1213
}) : super(
13-
const FeedbackPageState.initial(),
14+
FeedbackPageState.initial(),
1415
) {
1516
on<FeedbackPageSubmitEvent>(_onSubmit);
1617
on<FeedbackPageDescriptionChangedEvent>(_onDescriptionChange);
1718
}
1819

1920
void _onSubmit(
20-
FeedbackPageSubmitEvent event, Emitter<FeedbackPageState> emit) {
21-
// TODO: implement repository call
22-
bool submissionSuccessful = true;
23-
if (submissionSuccessful) {
21+
FeedbackPageSubmitEvent event, Emitter<FeedbackPageState> emit) async {
22+
try {
23+
int ratings = event.rating;
24+
AppetizerFeedback feedback = AppetizerFeedback(
25+
title: 'Feedback',
26+
message: event.description,
27+
mealId: event.mealId,
28+
// imageUrl: null,
29+
ratings: ratings,
30+
);
31+
await repo.newFeedback(feedback);
2432
emit(
2533
FeedbackPageState(
2634
rating: event.rating,
2735
description: event.description,
2836
submitted: true,
2937
error: false,
38+
mealId: event.mealId,
39+
),
40+
);
41+
} catch (e) {
42+
emit(
43+
FeedbackPageState(
44+
rating: event.rating,
45+
description: event.description,
46+
submitted: false,
47+
error: true,
48+
mealId: event.mealId,
3049
),
3150
);
3251
}
33-
// else {
34-
// emit(
35-
// FeedbackPageState(
36-
// rating: event.rating,
37-
// description: event.description,
38-
// submitted: false,
39-
// error: true,
40-
// ),
41-
// );
42-
// }
4352
}
4453

4554
void _onDescriptionChange(FeedbackPageDescriptionChangedEvent event,
@@ -50,7 +59,8 @@ class FeedbackPageBloc extends Bloc<FeedbackPageEvent, FeedbackPageState> {
5059
rating: state.rating,
5160
description: event.description,
5261
submitted: state.submitted,
53-
error: state.error,
62+
error: false,
63+
mealId: state.mealId,
5464
),
5565
);
5666
}

lib/presentation/feedback/bloc/feedback_page_event.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ class FeedbackPageSubmitEvent extends FeedbackPageEvent {
1111
const FeedbackPageSubmitEvent({
1212
required this.rating,
1313
required this.description,
14+
required this.mealId,
1415
});
15-
final List<int> rating;
16+
final int rating;
1617
final String description;
18+
final int mealId;
1719

1820
@override
19-
List<Object> get props => [rating, description];
21+
List<Object> get props => [rating, description, mealId];
2022
}
2123

2224
class FeedbackPageDescriptionChangedEvent extends FeedbackPageEvent {
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
part of 'feedback_page_bloc.dart';
22

3+
// ignore: must_be_immutable
34
class FeedbackPageState extends Equatable {
4-
const FeedbackPageState({
5+
FeedbackPageState({
56
required this.rating,
67
required this.description,
8+
required this.mealId,
79
required this.submitted,
810
required this.error,
911
});
1012

11-
const FeedbackPageState.initial()
12-
: rating = const [0, 0, 0, 0, 0],
13+
FeedbackPageState.initial()
14+
: rating = 0,
1315
description = '',
16+
mealId = 0,
1417
submitted = false,
1518
error = false;
1619

17-
final List<int> rating;
20+
int rating;
1821
final String description;
22+
final int mealId;
1923
final bool submitted;
2024
final bool error;
2125

2226
@override
23-
List<Object> get props => [rating, description, error];
27+
List<Object> get props => [rating, description, mealId, error];
2428
}

lib/presentation/feedback/components/FeedbackTile/feedback_tile.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ class FeedbackTile extends StatelessWidget {
99
const FeedbackTile({
1010
required this.title,
1111
required this.parentState,
12-
required this.index,
1312
super.key,
1413
});
1514

1615
final String title;
1716
final FeedbackPageState parentState;
18-
final int index;
1917

2018
@override
2119
Widget build(BuildContext context) {
@@ -44,7 +42,7 @@ class FeedbackTile extends StatelessWidget {
4442
onPressed: () {
4543
context.read<FeedbackTileBloc>().add(
4644
FeedbackRatingChangedEvent(newRating: index + 1));
47-
parentState.rating[this.index] = index + 1;
45+
parentState.rating = index + 1;
4846
},
4947
icon: index < state.rating
5048
? SvgPicture.asset('assets/images/filledStar.svg')

lib/presentation/feedback/feedback_view.dart

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@ import 'package:appetizer/presentation/feedback/components/feedback_banner.dart'
99
import 'package:auto_route/auto_route.dart';
1010
import 'package:flutter/material.dart';
1111
import 'package:flutter_bloc/flutter_bloc.dart';
12+
import 'package:fluttertoast/fluttertoast.dart';
1213

1314
@RoutePage()
1415
class FeedbackScreen extends StatelessWidget {
15-
FeedbackScreen({super.key});
16+
FeedbackScreen({required this.mealId, super.key});
1617
final TextEditingController textController = TextEditingController();
18+
final int mealId;
1719
static const List<String> feedbackHeadings = [
18-
"Ambience",
19-
"Hygiene and Cleanliness",
20-
"Weekly Menu",
21-
"Worker and Services",
22-
"Diet and Nutrition",
20+
"Your Feedback",
2321
];
2422

2523
@override
@@ -29,7 +27,7 @@ class FeedbackScreen extends StatelessWidget {
2927
body: BlocProvider(
3028
create: (context) =>
3129
FeedbackPageBloc(repo: context.read<FeedbackRepository>()),
32-
child: BlocBuilder<FeedbackPageBloc, FeedbackPageState>(
30+
child: BlocConsumer<FeedbackPageBloc, FeedbackPageState>(
3331
builder: (context, state) {
3432
return Column(
3533
children: [
@@ -52,17 +50,14 @@ class FeedbackScreen extends StatelessWidget {
5250
),
5351
),
5452
6.toVerticalSizedBox,
55-
...List.generate(feedbackHeadings.length, (ind) {
56-
return Padding(
57-
padding: EdgeInsets.symmetric(
58-
vertical: 2.toAutoScaledHeight),
59-
child: FeedbackTile(
60-
parentState: state,
61-
title: feedbackHeadings[ind],
62-
index: ind,
63-
),
64-
);
65-
}, growable: false),
53+
Padding(
54+
padding: EdgeInsets.symmetric(
55+
vertical: 2.toAutoScaledHeight),
56+
child: FeedbackTile(
57+
parentState: state,
58+
title: "Your Feedback",
59+
),
60+
),
6661
2.toVerticalSizedBox,
6762
Text(
6863
'If any other feeback, please describe below',
@@ -100,11 +95,36 @@ class FeedbackScreen extends StatelessWidget {
10095
Align(
10196
alignment: Alignment.bottomRight,
10297
child: BlackIconButton(
103-
onTap: context.router.pop,
104-
// onTap: () => context.read<FeedbackPageBloc>().add(
105-
// FeedbackPageSubmitEvent(
106-
// rating: state.rating,
107-
// description: state.description)),
98+
onTap: () {
99+
if (state.rating == 0) {
100+
Fluttertoast.showToast(
101+
msg: "Please rate before submitting!",
102+
toastLength: Toast.LENGTH_SHORT,
103+
gravity: ToastGravity.BOTTOM,
104+
timeInSecForIosWeb: 1,
105+
textColor: Colors.white,
106+
backgroundColor: AppTheme.red,
107+
fontSize: 12.toAutoScaledFont);
108+
return;
109+
}
110+
111+
if (state.description.trim().isEmpty) {
112+
Fluttertoast.showToast(
113+
msg: "Please describe your Feedback!",
114+
toastLength: Toast.LENGTH_SHORT,
115+
gravity: ToastGravity.BOTTOM,
116+
timeInSecForIosWeb: 1,
117+
textColor: Colors.white,
118+
backgroundColor: AppTheme.red,
119+
fontSize: 12.toAutoScaledFont);
120+
return;
121+
}
122+
context.read<FeedbackPageBloc>().add(
123+
FeedbackPageSubmitEvent(
124+
mealId: mealId,
125+
rating: state.rating,
126+
description: state.description));
127+
},
108128
title: "SUBMIT",
109129
width: 102.toAutoScaledWidth,
110130
icon: Icons.keyboard_double_arrow_right_sharp,
@@ -118,6 +138,29 @@ class FeedbackScreen extends StatelessWidget {
118138
],
119139
);
120140
},
141+
listener: (BuildContext context, FeedbackPageState state) {
142+
if (state.submitted) {
143+
Fluttertoast.showToast(
144+
msg: "Feedback submitted successfully!",
145+
toastLength: Toast.LENGTH_SHORT,
146+
gravity: ToastGravity.BOTTOM,
147+
timeInSecForIosWeb: 1,
148+
textColor: Colors.white,
149+
backgroundColor: AppTheme.green,
150+
fontSize: 12.toAutoScaledFont);
151+
context.router.pop();
152+
}
153+
if (state.error) {
154+
Fluttertoast.showToast(
155+
msg: state.description,
156+
toastLength: Toast.LENGTH_SHORT,
157+
gravity: ToastGravity.BOTTOM,
158+
timeInSecForIosWeb: 1,
159+
textColor: Colors.white,
160+
backgroundColor: AppTheme.red,
161+
fontSize: 16.0);
162+
}
163+
},
121164
),
122165
),
123166
);

lib/presentation/week_menu/components/DayMenu/menu_card.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class FeedbackOrCouponButton extends StatelessWidget {
128128
if (meal.isOutdated) {
129129
return GestureDetector(
130130
onTap: () {
131-
context.router.navigate(FeedbackRoute());
131+
context.router.navigate(FeedbackRoute(mealId: meal.id));
132132
},
133133
child: const FeedbackAndCouponWidget(taken: false, coupon: false),
134134
);

0 commit comments

Comments
 (0)