feat: legacy mobile apps created

This commit is contained in:
Achintha Isuru
2025-12-02 23:51:04 -05:00
parent 850441ca64
commit 8e7753b324
1519 changed files with 0 additions and 16 deletions

View File

@@ -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,
);
}
}

View File

@@ -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(
'Clients 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)],
);
}
}