Skip to content

Commit

Permalink
Merge pull request #282 from mdgspace/casper/feedback
Browse files Browse the repository at this point in the history
feat: integrates feedback with the backend
  • Loading branch information
A-Kashif108 authored Apr 13, 2024
2 parents 19bc848 + 5e9f2ca commit e57147a
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 193 deletions.
2 changes: 1 addition & 1 deletion lib/data/services/remote/api_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract class ApiService {
Future<List<FeedbackResponse>> responseOfFeedbacks();

@POST(ApiEndpoints.newFeedback)
Future<AppetizerFeedback> newFeedback(
Future<void> newFeedback(
@Body() Map<String, dynamic> map,
);

Expand Down
16 changes: 4 additions & 12 deletions lib/domain/models/feedback/appetizer_feedback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,18 @@ part 'appetizer_feedback.g.dart';

@JsonSerializable(fieldRename: FieldRename.snake)
class AppetizerFeedback {
int id;
String type;
String title;
String message;
int timestamp;
dynamic mealId;
dynamic imageUrl;
int dateIssue;
dynamic response;
// dynamic imageUrl;
int ratings;

AppetizerFeedback({
required this.id,
required this.type,
required this.title,
required this.message,
required this.timestamp,
required this.mealId,
required this.imageUrl,
required this.dateIssue,
required this.response,
// required this.imageUrl,
required this.ratings,
});

factory AppetizerFeedback.fromJson(Map<String, dynamic> json) =>
Expand Down
9 changes: 5 additions & 4 deletions lib/domain/repositories/feedback_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ class FeedbackRepository {
}
}

Future<AppetizerFeedback> newFeedback(AppetizerFeedback feedback) async {
Future<void> newFeedback(AppetizerFeedback feedback) async {
Map<String, dynamic> map = {
'type': feedback.type,
'title': feedback.title,
'message': feedback.message,
'date_issue': feedback.dateIssue,
'meal_id': feedback.mealId,
'ratings': feedback.ratings,
// 'image_url': feedback.imageUrl,
};
try {
return await _apiService.newFeedback(map);
await _apiService.newFeedback(map);
} catch (e) {
debugPrint(e.toString());
throw Failure(AppConstants.GENERIC_FAILURE);
Expand Down
42 changes: 26 additions & 16 deletions lib/presentation/feedback/bloc/feedback_page_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:appetizer/domain/models/feedback/appetizer_feedback.dart';
import 'package:appetizer/domain/repositories/feedback_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
Expand All @@ -10,36 +11,44 @@ class FeedbackPageBloc extends Bloc<FeedbackPageEvent, FeedbackPageState> {
FeedbackPageBloc({
required this.repo,
}) : super(
const FeedbackPageState.initial(),
FeedbackPageState.initial(),
) {
on<FeedbackPageSubmitEvent>(_onSubmit);
on<FeedbackPageDescriptionChangedEvent>(_onDescriptionChange);
}

void _onSubmit(
FeedbackPageSubmitEvent event, Emitter<FeedbackPageState> emit) {
// TODO: implement repository call
bool submissionSuccessful = true;
if (submissionSuccessful) {
FeedbackPageSubmitEvent event, Emitter<FeedbackPageState> emit) async {
try {
int ratings = event.rating;
AppetizerFeedback feedback = AppetizerFeedback(
title: 'Feedback',
message: event.description,
mealId: event.mealId,
// imageUrl: null,
ratings: ratings,
);
await repo.newFeedback(feedback);
emit(
FeedbackPageState(
rating: event.rating,
description: event.description,
submitted: true,
error: false,
mealId: event.mealId,
),
);
} catch (e) {
emit(
FeedbackPageState(
rating: event.rating,
description: event.description,
submitted: false,
error: true,
mealId: event.mealId,
),
);
}
// else {
// emit(
// FeedbackPageState(
// rating: event.rating,
// description: event.description,
// submitted: false,
// error: true,
// ),
// );
// }
}

void _onDescriptionChange(FeedbackPageDescriptionChangedEvent event,
Expand All @@ -50,7 +59,8 @@ class FeedbackPageBloc extends Bloc<FeedbackPageEvent, FeedbackPageState> {
rating: state.rating,
description: event.description,
submitted: state.submitted,
error: state.error,
error: false,
mealId: state.mealId,
),
);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/presentation/feedback/bloc/feedback_page_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ class FeedbackPageSubmitEvent extends FeedbackPageEvent {
const FeedbackPageSubmitEvent({
required this.rating,
required this.description,
required this.mealId,
});
final List<int> rating;
final int rating;
final String description;
final int mealId;

@override
List<Object> get props => [rating, description];
List<Object> get props => [rating, description, mealId];
}

class FeedbackPageDescriptionChangedEvent extends FeedbackPageEvent {
Expand Down
14 changes: 9 additions & 5 deletions lib/presentation/feedback/bloc/feedback_page_state.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
part of 'feedback_page_bloc.dart';

// ignore: must_be_immutable
class FeedbackPageState extends Equatable {
const FeedbackPageState({
FeedbackPageState({
required this.rating,
required this.description,
required this.mealId,
required this.submitted,
required this.error,
});

const FeedbackPageState.initial()
: rating = const [0, 0, 0, 0, 0],
FeedbackPageState.initial()
: rating = 0,
description = '',
mealId = 0,
submitted = false,
error = false;

final List<int> rating;
int rating;
final String description;
final int mealId;
final bool submitted;
final bool error;

@override
List<Object> get props => [rating, description, error];
List<Object> get props => [rating, description, mealId, error];
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ class FeedbackTile extends StatelessWidget {
const FeedbackTile({
required this.title,
required this.parentState,
required this.index,
super.key,
});

final String title;
final FeedbackPageState parentState;
final int index;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -44,7 +42,7 @@ class FeedbackTile extends StatelessWidget {
onPressed: () {
context.read<FeedbackTileBloc>().add(
FeedbackRatingChangedEvent(newRating: index + 1));
parentState.rating[this.index] = index + 1;
parentState.rating = index + 1;
},
icon: index < state.rating
? SvgPicture.asset('assets/images/filledStar.svg')
Expand Down
89 changes: 66 additions & 23 deletions lib/presentation/feedback/feedback_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import 'package:appetizer/presentation/feedback/components/feedback_banner.dart'
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart';

@RoutePage()
class FeedbackScreen extends StatelessWidget {
FeedbackScreen({super.key});
FeedbackScreen({required this.mealId, super.key});
final TextEditingController textController = TextEditingController();
final int mealId;
static const List<String> feedbackHeadings = [
"Ambience",
"Hygiene and Cleanliness",
"Weekly Menu",
"Worker and Services",
"Diet and Nutrition",
"Your Feedback",
];

@override
Expand All @@ -29,7 +27,7 @@ class FeedbackScreen extends StatelessWidget {
body: BlocProvider(
create: (context) =>
FeedbackPageBloc(repo: context.read<FeedbackRepository>()),
child: BlocBuilder<FeedbackPageBloc, FeedbackPageState>(
child: BlocConsumer<FeedbackPageBloc, FeedbackPageState>(
builder: (context, state) {
return Column(
children: [
Expand All @@ -52,17 +50,14 @@ class FeedbackScreen extends StatelessWidget {
),
),
6.toVerticalSizedBox,
...List.generate(feedbackHeadings.length, (ind) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: 2.toAutoScaledHeight),
child: FeedbackTile(
parentState: state,
title: feedbackHeadings[ind],
index: ind,
),
);
}, growable: false),
Padding(
padding: EdgeInsets.symmetric(
vertical: 2.toAutoScaledHeight),
child: FeedbackTile(
parentState: state,
title: "Your Feedback",
),
),
2.toVerticalSizedBox,
Text(
'If any other feeback, please describe below',
Expand Down Expand Up @@ -100,11 +95,36 @@ class FeedbackScreen extends StatelessWidget {
Align(
alignment: Alignment.bottomRight,
child: BlackIconButton(
onTap: context.router.pop,
// onTap: () => context.read<FeedbackPageBloc>().add(
// FeedbackPageSubmitEvent(
// rating: state.rating,
// description: state.description)),
onTap: () {
if (state.rating == 0) {
Fluttertoast.showToast(
msg: "Please rate before submitting!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
textColor: Colors.white,
backgroundColor: AppTheme.red,
fontSize: 12.toAutoScaledFont);
return;
}

if (state.description.trim().isEmpty) {
Fluttertoast.showToast(
msg: "Please describe your Feedback!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
textColor: Colors.white,
backgroundColor: AppTheme.red,
fontSize: 12.toAutoScaledFont);
return;
}
context.read<FeedbackPageBloc>().add(
FeedbackPageSubmitEvent(
mealId: mealId,
rating: state.rating,
description: state.description));
},
title: "SUBMIT",
width: 102.toAutoScaledWidth,
icon: Icons.keyboard_double_arrow_right_sharp,
Expand All @@ -118,6 +138,29 @@ class FeedbackScreen extends StatelessWidget {
],
);
},
listener: (BuildContext context, FeedbackPageState state) {
if (state.submitted) {
Fluttertoast.showToast(
msg: "Feedback submitted successfully!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
textColor: Colors.white,
backgroundColor: AppTheme.green,
fontSize: 12.toAutoScaledFont);
context.router.pop();
}
if (state.error) {
Fluttertoast.showToast(
msg: state.description,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
textColor: Colors.white,
backgroundColor: AppTheme.red,
fontSize: 16.0);
}
},
),
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class FeedbackOrCouponButton extends StatelessWidget {
if (meal.isOutdated) {
return GestureDetector(
onTap: () {
context.router.navigate(FeedbackRoute());
context.router.navigate(FeedbackRoute(mealId: meal.id));
},
child: const FeedbackAndCouponWidget(taken: false, coupon: false),
);
Expand Down
Loading

0 comments on commit e57147a

Please sign in to comment.