Skip to content

Commit

Permalink
feat(filters): Added job offer list filter modal
Browse files Browse the repository at this point in the history
  • Loading branch information
DCampagnola committed May 1, 2023
1 parent f927e07 commit afd46b6
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 25 deletions.
11 changes: 9 additions & 2 deletions lib/job_offer_list/bloc/job_offer_list_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ part 'job_offer_list_state.dart';

typedef OpenJobOfferCallback = void Function(JobOffer jobOffer);
typedef OpenFreelanceCallback = void Function(Freelance freelance);
typedef OpenFilterDialogCallback = Future<void> Function(JobOfferListBloc self);

class JobOfferListBloc extends Bloc<JobOfferListEvent, JobOfferListState> {
JobOfferListBloc({
required JobOfferRepository jobOfferRepository,
required OpenJobOfferCallback openJobOfferDetailPage,
required OpenFreelanceCallback openFreelanceDetailPage,
required OpenFilterDialogCallback openFilterDialog,
}) : _jobOfferRepository = jobOfferRepository,
_openJobOfferDetailPageCallback = openJobOfferDetailPage,
_openFreelanceDetailPageCallback = openFreelanceDetailPage,
_openFilterDialogCallback = openFilterDialog,
super(
const JobOfferListInitial(
[],
Expand Down Expand Up @@ -59,6 +62,7 @@ class JobOfferListBloc extends Bloc<JobOfferListEvent, JobOfferListState> {
late StreamSubscription<List<Freelance>> _freelanceListSubscription;
final OpenJobOfferCallback _openJobOfferDetailPageCallback;
final OpenFreelanceCallback _openFreelanceDetailPageCallback;
final OpenFilterDialogCallback _openFilterDialogCallback;

void _handleFreelanceListChange(
FreelanceListChange event,
Expand Down Expand Up @@ -129,10 +133,10 @@ class JobOfferListBloc extends Bloc<JobOfferListEvent, JobOfferListState> {
_openJobOfferDetailPageCallback(event.jobOffer);
}

void _handleOpportunityFilterTap(
Future<void> _handleOpportunityFilterTap(
OpportunityFilterTap event,
Emitter<JobOfferListState> emit,
) {
) async {
emit(
state is JobOfferListFilled
? OpportunityFilterEditing(
Expand All @@ -151,6 +155,9 @@ class JobOfferListBloc extends Bloc<JobOfferListEvent, JobOfferListState> {
)
: state,
);
await _openFilterDialogCallback(
this,
);
}

void _handleCancelFilterTap(
Expand Down
125 changes: 125 additions & 0 deletions lib/job_offer_list/dialog/job_offer_list_filter_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fudeo_hackaton/job_offer_list/bloc/job_offer_list_bloc.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/filters/dialog/filter_group.dart';
import 'package:fudeo_hackaton/theme/buttons.dart';
import 'package:fudeo_hackaton/theme/colors.dart';
import 'package:fudeo_hackaton/theme/fonts.dart';
import 'package:phosphor_flutter/phosphor_flutter.dart';

class JobOfferListFilterDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<JobOfferListBloc, JobOfferListState>(
builder: (context, state) {
if (state is! OpportunityFilterEditing) {
return const ColoredBox(
color: AppColors.accentLight,
child: Center(
child: CircularProgressIndicator(),
),
);
}
return ColoredBox(
color: AppColors.accentLight,
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BackButton(
onPressed: () => _cancelFilter(context),
),
const Text(
'Filtri',
style: AppFonts.filtersDialogTitle,
),
TextButton(
onPressed: () => _resetFilter(context),
child: const Text(
'Reset',
style: AppFonts.filtersDialogButton,
),
),
],
),
const SizedBox(height: 12),
FilterGroup(
title: 'Team',
icon: PhosphorIcons.regular.users,
filters: const [
Filter.fullRemote,
Filter.hybrid,
Filter.onSite,
],
),
FilterGroup(
title: 'Seniority',
icon: PhosphorIcons.regular.code,
filters: const [
Filter.junior,
Filter.mid,
Filter.senior,
],
),
FilterGroup(
title: 'Contratto',
icon: PhosphorIcons.regular.clock,
filters: const [
Filter.fullTime,
Filter.partTime,
],
),
],
),
),
),
AppButton(
action: () => _applyFilter(context),
text: 'Applica filtri',
iconData: PhosphorIcons.regular.check,
),
],
),
),
);
},
);
}

static Future<void> show(BuildContext context, JobOfferListBloc bloc) {
final size = MediaQuery.of(context).size;
return showModalBottomSheet<void>(
isScrollControlled: true,
constraints: BoxConstraints(
maxHeight: size.height * 0.9,
),
isDismissible: false,
context: context,
builder: (context) =>
BlocProvider.value(value: bloc, child: JobOfferListFilterDialog()),
);
}

Future<void> _applyFilter(BuildContext context) async {
Navigator.of(context).pop();
BlocProvider.of<JobOfferListBloc>(context).add(ApplyFilterTap());
}

void _cancelFilter(BuildContext context) {
Navigator.of(context).pop();
BlocProvider.of<JobOfferListBloc>(context).add(CancelFilterTap());
}

void _resetFilter(BuildContext context) {
Navigator.of(context).pop();
BlocProvider.of<JobOfferListBloc>(context).add(EmptyFilterTap());
}
}
40 changes: 19 additions & 21 deletions lib/job_offer_list/view/job_offer_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fudeo_hackaton/job_detail/job_detail.dart';
import 'package:fudeo_hackaton/job_detail/view/project_detail_page.dart';
import 'package:fudeo_hackaton/job_offer_list/bloc/job_offer_list_bloc.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/filters/dialog/FiltersDialogArea.dart';
import 'package:fudeo_hackaton/job_offer_list/dialog/job_offer_list_filter_dialog.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/filters/filters.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/no_results/no_results_message.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/opportunity_type_toggle.dart';
Expand Down Expand Up @@ -53,6 +53,10 @@ class JobOfferListPage extends StatelessWidget {
),
),
),
openFilterDialog: (bloc) => JobOfferListFilterDialog.show(
context,
bloc,
),
),
child: const JobOfferListView(),
),
Expand Down Expand Up @@ -93,29 +97,23 @@ class JobListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bloc = context.read<JobOfferListBloc>();
return FiltersDialogArea(
child: BlocBuilder<JobOfferListBloc, JobOfferListState>(
builder: (context, state) => state.filteredOpportunities.isNotEmpty
? ListView(
children: List.of(
state.filteredOpportunities.map(
(o) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 16),
child: OpportunityCard(
opportunity: o,
onTap: () => bloc.add(OpportunityTap(o)),
),
return BlocBuilder<JobOfferListBloc, JobOfferListState>(
builder: (context, state) => state.filteredOpportunities.isNotEmpty
? ListView(
children: List.of(
state.filteredOpportunities.map(
(o) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 16),
child: OpportunityCard(
opportunity: o,
onTap: () => bloc.add(OpportunityTap(o)),
),
),
),
)
: const NoResultsMessage(),
),
),
)
: const NoResultsMessage(),
);
}

void _onJobOfferTap(BuildContext context, JobOffer e) {
BlocProvider.of<JobOfferListBloc>(context).add(JobOfferListTap(e));
}
}
3 changes: 1 addition & 2 deletions lib/job_offer_list/widget/filters/filters.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fudeo_hackaton/job_offer_list/bloc/job_offer_list_bloc.dart';
import 'package:fudeo_hackaton/job_offer_list/widget/filters/active_filters.dart';
Expand All @@ -26,6 +24,7 @@ class Filters extends StatelessWidget {
),
BlocBuilder<JobOfferListBloc, JobOfferListState>(
builder: (context, state) {
final bloc = BlocProvider.of<JobOfferListBloc>(context);
return Visibility(
visible: state.selectedType == OpportunityType.jobOffer,
child: Stack(
Expand Down

0 comments on commit afd46b6

Please sign in to comment.