feat: Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/entity/staff_contact_entity.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
|
||||
import 'package:krow/core/presentation/widgets/staff_position_details_widget.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/check_box.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_dropdown.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_input.dart';
|
||||
import 'package:krow/features/rate_staff/domain/bloc/rating_staff_bloc.dart';
|
||||
import 'package:krow/features/rate_staff/presentation/widgets/rating_widget.dart';
|
||||
|
||||
@RoutePage()
|
||||
class RateStaffScreen extends StatelessWidget implements AutoRouteWrapper {
|
||||
final StaffContact staff;
|
||||
final TextEditingController _reasonController = TextEditingController();
|
||||
|
||||
RateStaffScreen({super.key, required this.staff});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(
|
||||
titleText: 'Rate Staff',
|
||||
),
|
||||
body: BlocConsumer<RatingStaffBloc, RatingStaffState>(
|
||||
listener: (context, state) {
|
||||
if (state.error.isNotEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.error),
|
||||
backgroundColor: AppColors.statusError,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (state.success) {
|
||||
context.router.maybePop();
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return ScrollLayoutHelper(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
upperWidget: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Gap(16),
|
||||
StaffPositionAvatar(
|
||||
imageUrl: staff.photoUrl,
|
||||
userName: '${staff.firstName} ${staff.lastName}'),
|
||||
const Gap(16),
|
||||
StaffContactsWidget(staff: staff),
|
||||
const Gap(12),
|
||||
StaffPositionDetailsWidget(staff: staff),
|
||||
const Gap(12),
|
||||
const RatingWidget(),
|
||||
if (state.rating < 3) ..._blackListCheckbox(context, state),
|
||||
const Gap(24),
|
||||
],
|
||||
),
|
||||
lowerWidget: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 36, left: 16, right: 16),
|
||||
child: KwButton.primary(
|
||||
disabled: state.rating < 3 && state.reason == null,
|
||||
onPressed: () {
|
||||
BlocProvider.of<RatingStaffBloc>(context).add(
|
||||
RatingSubmitEvent(),
|
||||
);
|
||||
},
|
||||
label: 'Submit Review'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _blackListCheckbox(
|
||||
BuildContext context, RatingStaffState state) {
|
||||
return [
|
||||
const Gap(12),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<RatingStaffBloc>(context)
|
||||
.add(StaffBlacklistToggleEvent());
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(32),
|
||||
KWCheckBox(
|
||||
value: state.blackListed,
|
||||
style: CheckBoxStyle.black,
|
||||
),
|
||||
const Gap(6),
|
||||
Text(
|
||||
'Don\'t assign to my Events anymore',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
const Gap(16),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24, left: 16, right: 16),
|
||||
child: KwDropdown<String>(
|
||||
title: 'Reason',
|
||||
items: ['Lack of responsibility', 'Unpreparedness', 'Poor communication','Unprofessional behavior','Ignoring Responsibilities']
|
||||
.map((e) => KwDropDownItem(data: e, title: e))
|
||||
.toList(),
|
||||
horizontalPadding: 16,
|
||||
hintText: 'Select a reason',
|
||||
selectedItem: state.reason != null
|
||||
? KwDropDownItem(data: state.reason!, title: state.reason!)
|
||||
: null,
|
||||
onSelected: (String item) {
|
||||
BlocProvider.of<RatingStaffBloc>(context)
|
||||
.add(StaffReasonSelectedEvent(item));
|
||||
},
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0, left: 16, right: 16),
|
||||
child: KwTextInput(
|
||||
onChanged: (String value) {
|
||||
BlocProvider.of<RatingStaffBloc>(context)
|
||||
.add(StaffReasonDetailsChangeEvent(value));
|
||||
},
|
||||
minHeight: 144,
|
||||
maxLength: 300,
|
||||
showCounter: true,
|
||||
radius: 12,
|
||||
title: 'Additional Details',
|
||||
hintText: 'Enter your reason here...',
|
||||
controller: _reasonController,
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => RatingStaffBloc(staff),
|
||||
child: this,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/gen/assets.gen.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_box_decorations.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/features/rate_staff/domain/bloc/rating_staff_bloc.dart';
|
||||
|
||||
class RatingWidget extends StatelessWidget {
|
||||
const RatingWidget({super.key,});
|
||||
|
||||
final double maxRating = 5.0; // Maximum rating, e.g., 5
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RatingStaffBloc, RatingStaffState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, top: 8),
|
||||
decoration: KwBoxDecorations.primaryLight12,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Client’s rate'.toUpperCase(),
|
||||
style: AppTextStyles.captionReg
|
||||
.copyWith(color: AppColors.blackCaptionText),
|
||||
),
|
||||
state.rating >= 3
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<RatingStaffBloc>(context)
|
||||
.add(StaffFavoriteToggleEvent());
|
||||
},
|
||||
child: state.favorite
|
||||
? Assets.images.icons.heart.svg()
|
||||
: Assets.images.icons.heartEmpty.svg(),
|
||||
)
|
||||
: const SizedBox(height: 20)
|
||||
],
|
||||
),
|
||||
const Gap(4),
|
||||
Center(
|
||||
child: Text(state.rating.toStringAsFixed(1),
|
||||
style: AppTextStyles.headingH0),
|
||||
),
|
||||
const Gap(4),
|
||||
_buildRating(state.rating, context),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
_buildRating(int rating, BuildContext context) {
|
||||
List<Widget> stars = [];
|
||||
for (int i = 1; i <= maxRating; i++) {
|
||||
var star;
|
||||
if (i <= rating) {
|
||||
star = (Assets.images.icons.ratingStar.star.svg());
|
||||
} else {
|
||||
star = (Assets.images.icons.ratingStar.starEmpty.svg());
|
||||
}
|
||||
stars.add(GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<RatingStaffBloc>(context).add(RatingChangedEvent(i));
|
||||
},
|
||||
child: star,
|
||||
));
|
||||
}
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [const Gap(28), ...stars, const Gap(28)],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user