feat: Add Headline 1 Bold style and refactor ShiftDetailsPage and FindShiftsTab layout

This commit is contained in:
Achintha Isuru
2026-02-16 12:58:05 -05:00
parent b3b84b6293
commit e6b512ee84
8 changed files with 151 additions and 146 deletions

View File

@@ -173,6 +173,14 @@ class UiTypography {
color: UiColors.textPrimary, color: UiColors.textPrimary,
); );
/// Headline 1 Bold - Font: Instrument Sans, Size: 26, Height: 1.5 (#121826)
static final TextStyle headline1b = _primaryBase.copyWith(
fontWeight: FontWeight.w600,
fontSize: 26,
height: 1.5,
color: UiColors.textPrimary,
);
/// Headline 2 Medium - Font: Instrument Sans, Size: 20, Height: 1.5 (#121826) /// Headline 2 Medium - Font: Instrument Sans, Size: 20, Height: 1.5 (#121826)
static final TextStyle headline2m = _primaryBase.copyWith( static final TextStyle headline2m = _primaryBase.copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,

View File

@@ -84,13 +84,6 @@ class _ShiftCardState extends State<ShiftCard> {
color: UiColors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(UiConstants.radiusBase),
border: Border.all(color: UiColors.border), border: Border.all(color: UiColors.border),
boxShadow: [
BoxShadow(
color: UiColors.black.withValues(alpha: 0.05),
blurRadius: 2,
offset: const Offset(0, 1),
),
],
), ),
child: Row( child: Row(
children: [ children: [

View File

@@ -14,9 +14,13 @@ import '../widgets/shift_location_map.dart';
class ShiftDetailsPage extends StatefulWidget { class ShiftDetailsPage extends StatefulWidget {
final String shiftId; final String shiftId;
final Shift? shift; final Shift shift;
const ShiftDetailsPage({super.key, required this.shiftId, this.shift}); const ShiftDetailsPage({
super.key,
required this.shiftId,
required this.shift,
});
@override @override
State<ShiftDetailsPage> createState() => _ShiftDetailsPageState(); State<ShiftDetailsPage> createState() => _ShiftDetailsPageState();
@@ -86,12 +90,11 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
Text( Text(
value, value,
style: UiTypography.title1m.copyWith(fontWeight: FontWeight.w700).textPrimary, style: UiTypography.title1m
), .copyWith(fontWeight: FontWeight.w700)
Text( .textPrimary,
label,
style: UiTypography.footnote2r.textSecondary,
), ),
Text(label, style: UiTypography.footnote2r.textSecondary),
], ],
), ),
); );
@@ -109,12 +112,16 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
Text( Text(
label, label,
style: UiTypography.footnote2b.copyWith( style: UiTypography.footnote2b.copyWith(
color: UiColors.textSecondary, letterSpacing: 0.5), color: UiColors.textSecondary,
letterSpacing: 0.5,
),
), ),
const SizedBox(height: UiConstants.space1), const SizedBox(height: UiConstants.space1),
Text( Text(
_formatTime(time), _formatTime(time),
style: UiTypography.title1m.copyWith(fontWeight: FontWeight.w700).textPrimary, style: UiTypography.title1m
.copyWith(fontWeight: FontWeight.w700)
.textPrimary,
), ),
], ],
), ),
@@ -124,14 +131,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<ShiftDetailsBloc>( return BlocProvider<ShiftDetailsBloc>(
create: (_) => create: (_) => Modular.get<ShiftDetailsBloc>()
Modular.get<ShiftDetailsBloc>() ..add(
..add( LoadShiftDetailsEvent(widget.shiftId, roleId: widget.shift?.roleId),
LoadShiftDetailsEvent( ),
widget.shiftId,
roleId: widget.shift?.roleId,
),
),
child: BlocListener<ShiftDetailsBloc, ShiftDetailsState>( child: BlocListener<ShiftDetailsBloc, ShiftDetailsState>(
listener: (context, state) { listener: (context, state) {
if (state is ShiftActionSuccess || state is ShiftDetailsError) { if (state is ShiftActionSuccess || state is ShiftDetailsError) {
@@ -164,30 +167,16 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
); );
} }
Shift? displayShift; Shift? displayShift = widget.shift;
if (state is ShiftDetailsLoaded) {
displayShift = state.shift;
} else {
displayShift = widget.shift;
}
final i18n = Translations.of(context).staff_shifts.shift_details; final i18n = Translations.of(context).staff_shifts.shift_details;
if (displayShift == null) {
return Scaffold(
body: Center(child: Text(Translations.of(context).staff_shifts.list.no_shifts)),
);
}
final duration = _calculateDuration(displayShift); final duration = _calculateDuration(displayShift);
final estimatedTotal = final estimatedTotal =
displayShift.totalValue ?? (displayShift.hourlyRate * duration); displayShift.totalValue ?? (displayShift.hourlyRate * duration);
final openSlots =
(displayShift.requiredSlots ?? 0) -
(displayShift.filledSlots ?? 0);
return Scaffold( return Scaffold(
appBar: UiAppBar( appBar: UiAppBar(
title: displayShift.title,
centerTitle: false, centerTitle: false,
onLeadingPressed: () => Modular.to.toShifts(), onLeadingPressed: () => Modular.to.toShifts(),
), ),
@@ -199,44 +188,49 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Vendor Section // Role & Client Section
Column( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: UiConstants.space4,
children: [ children: [
Text( Container(
i18n.vendor, width: 48,
style: UiTypography.titleUppercase4b.textSecondary, height: 48,
decoration: BoxDecoration(
color: UiColors.background,
borderRadius: BorderRadius.circular(
UiConstants.radiusBase,
),
border: Border.all(color: UiColors.border),
),
child: const Center(
child: Icon(
UiIcons.briefcase,
color: UiColors.primary,
size: 24,
),
),
), ),
const SizedBox(height: UiConstants.space2),
Row( Expanded(
children: [ child: Column(
SizedBox( crossAxisAlignment: CrossAxisAlignment.start,
width: 24, children: [
height: 24, Text(
child: displayShift.logoUrl != null displayShift.title,
? ClipRRect( style:
borderRadius: BorderRadius.circular( UiTypography.headline1b.textPrimary,
UiConstants.radiusMdValue, ),
), Text(
child: Image.network( displayShift.clientName,
displayShift.logoUrl!, style: UiTypography.body1m.textSecondary,
fit: BoxFit.cover, ),
), Text(
) displayShift.locationAddress,
: const Center( style: UiTypography.body2r.textSecondary,
child: Icon( ),
UiIcons.briefcase, ],
color: UiColors.primary, ),
size: 20,
),
),
),
const SizedBox(width: UiConstants.space2),
Text(
displayShift.clientName,
style: UiTypography.headline5m.textPrimary,
),
],
), ),
], ],
), ),
@@ -248,7 +242,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
children: [ children: [
Text( Text(
i18n.shift_date, i18n.shift_date,
style: UiTypography.titleUppercase4b.textSecondary, style:
UiTypography.titleUppercase4b.textSecondary,
), ),
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
Row( Row(
@@ -276,7 +271,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
child: _buildStatCard( child: _buildStatCard(
UiIcons.dollar, UiIcons.dollar,
"\$${estimatedTotal.toStringAsFixed(0)}", "\$${estimatedTotal.toStringAsFixed(0)}",
"Total", "Total",
), ),
), ),
const SizedBox(width: UiConstants.space4), const SizedBox(width: UiConstants.space4),
@@ -291,7 +286,7 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
Expanded( Expanded(
child: _buildStatCard( child: _buildStatCard(
UiIcons.clock, UiIcons.clock,
"${duration.toStringAsFixed(1)}", "${duration.toStringAsFixed(1)}",
"Hours", "Hours",
), ),
), ),
@@ -319,14 +314,14 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
), ),
const SizedBox(height: UiConstants.space6), const SizedBox(height: UiConstants.space6),
// Location Section (New with Map) // Location Section (New with Map)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"LOCATION", "LOCATION",
style: UiTypography.titleUppercase4b.textSecondary, style:
UiTypography.titleUppercase4b.textSecondary,
), ),
const SizedBox(height: UiConstants.space3), const SizedBox(height: UiConstants.space3),
Row( Row(
@@ -350,13 +345,13 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
).showSnackBar( ).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
displayShift!.locationAddress.isNotEmpty displayShift!
? displayShift!.locationAddress .locationAddress
: displayShift!.location, .isNotEmpty
), ? displayShift!.locationAddress
duration: const Duration( : displayShift!.location,
seconds: 3,
), ),
duration: const Duration(seconds: 3),
), ),
); );
}, },
@@ -364,12 +359,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
UiIcons.navigation, UiIcons.navigation,
size: UiConstants.iconXs, size: UiConstants.iconXs,
), ),
label: const Text( label: const Text("Get direction"),
"Get direction",
),
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: foregroundColor: UiColors.textPrimary,
UiColors.textPrimary,
side: const BorderSide( side: const BorderSide(
color: UiColors.border, color: UiColors.border,
), ),
@@ -401,7 +393,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
if ((displayShift.description ?? '').isNotEmpty) ...[ if ((displayShift.description ?? '').isNotEmpty) ...[
Text( Text(
i18n.job_description, i18n.job_description,
style: UiTypography.titleUppercase4b.textSecondary, style:
UiTypography.titleUppercase4b.textSecondary,
), ),
const SizedBox(height: UiConstants.space2), const SizedBox(height: UiConstants.space2),
Text( Text(
@@ -420,7 +413,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
UiConstants.space5, UiConstants.space5,
UiConstants.space4, UiConstants.space4,
UiConstants.space5, UiConstants.space5,
MediaQuery.of(context).padding.bottom + UiConstants.space4, MediaQuery.of(context).padding.bottom +
UiConstants.space4,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: UiColors.white, color: UiColors.white,
@@ -444,11 +438,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
); );
} }
void _bookShift( void _bookShift(BuildContext context, Shift shift) {
BuildContext context, final i18n = Translations.of(
Shift shift, context,
) { ).staff_shifts.shift_details.book_dialog;
final i18n = Translations.of(context).staff_shifts.shift_details.book_dialog;
showDialog( showDialog(
context: context, context: context,
builder: (ctx) => AlertDialog( builder: (ctx) => AlertDialog(
@@ -471,10 +464,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
), ),
); );
}, },
style: TextButton.styleFrom( style: TextButton.styleFrom(foregroundColor: UiColors.success),
foregroundColor: UiColors.success, child: Text(
Translations.of(context).staff_shifts.shift_details.apply_now,
), ),
child: Text(Translations.of(context).staff_shifts.shift_details.apply_now),
), ),
], ],
), ),
@@ -482,7 +475,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
} }
void _declineShift(BuildContext context, String id) { void _declineShift(BuildContext context, String id) {
final i18n = Translations.of(context).staff_shifts.shift_details.decline_dialog; final i18n = Translations.of(
context,
).staff_shifts.shift_details.decline_dialog;
showDialog( showDialog(
context: context, context: context,
builder: (ctx) => AlertDialog( builder: (ctx) => AlertDialog(
@@ -499,10 +494,10 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
context, context,
).add(DeclineShiftDetailsEvent(id)); ).add(DeclineShiftDetailsEvent(id));
}, },
style: TextButton.styleFrom( style: TextButton.styleFrom(foregroundColor: UiColors.destructive),
foregroundColor: UiColors.destructive, child: Text(
Translations.of(context).staff_shifts.shift_details.decline,
), ),
child: Text(Translations.of(context).staff_shifts.shift_details.decline),
), ),
], ],
), ),
@@ -513,7 +508,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
if (_actionDialogOpen) return; if (_actionDialogOpen) return;
_actionDialogOpen = true; _actionDialogOpen = true;
_isApplying = true; _isApplying = true;
final i18n = Translations.of(context).staff_shifts.shift_details.applying_dialog; final i18n = Translations.of(
context,
).staff_shifts.shift_details.applying_dialog;
showDialog( showDialog(
context: context, context: context,
useRootNavigator: true, useRootNavigator: true,
@@ -590,10 +587,14 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
children: [ children: [
Expanded( Expanded(
child: OutlinedButton( child: OutlinedButton(
onPressed: () => BlocProvider.of<ShiftDetailsBloc>(context).add(DeclineShiftDetailsEvent(shift.id)), onPressed: () => BlocProvider.of<ShiftDetailsBloc>(
context,
).add(DeclineShiftDetailsEvent(shift.id)),
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: UiColors.destructive, foregroundColor: UiColors.destructive,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
side: const BorderSide(color: UiColors.destructive), side: const BorderSide(color: UiColors.destructive),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(UiConstants.radiusBase),
@@ -605,11 +606,15 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
const SizedBox(width: UiConstants.space4), const SizedBox(width: UiConstants.space4),
Expanded( Expanded(
child: ElevatedButton( child: ElevatedButton(
onPressed: () => BlocProvider.of<ShiftDetailsBloc>(context).add(BookShiftDetailsEvent(shift.id, roleId: shift.roleId)), onPressed: () => BlocProvider.of<ShiftDetailsBloc>(
context,
).add(BookShiftDetailsEvent(shift.id, roleId: shift.roleId)),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary, backgroundColor: UiColors.primary,
foregroundColor: UiColors.white, foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(UiConstants.radiusBase),
), ),
@@ -630,13 +635,18 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
onPressed: () => _declineShift(context, shift.id), onPressed: () => _declineShift(context, shift.id),
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: UiColors.textSecondary, foregroundColor: UiColors.textSecondary,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
side: const BorderSide(color: UiColors.border), side: const BorderSide(color: UiColors.border),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(UiConstants.radiusBase),
), ),
), ),
child: Text(i18n.decline, style: UiTypography.body2b.textSecondary), child: Text(
i18n.decline,
style: UiTypography.body2b.textSecondary,
),
), ),
), ),
const SizedBox(width: UiConstants.space4), const SizedBox(width: UiConstants.space4),
@@ -646,7 +656,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: UiColors.primary, backgroundColor: UiColors.primary,
foregroundColor: UiColors.white, foregroundColor: UiColors.white,
padding: const EdgeInsets.symmetric(vertical: UiConstants.space4), padding: const EdgeInsets.symmetric(
vertical: UiConstants.space4,
),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(UiConstants.radiusBase),
), ),
@@ -661,5 +673,4 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
return const SizedBox(); return const SizedBox();
} }
} }

View File

@@ -29,7 +29,6 @@ class _ShiftsPageState extends State<ShiftsPage> {
super.initState(); super.initState();
_activeTab = widget.initialTab ?? 'myshifts'; _activeTab = widget.initialTab ?? 'myshifts';
_selectedDate = widget.selectedDate; _selectedDate = widget.selectedDate;
print('ShiftsPage init: initialTab=$_activeTab');
_prioritizeFind = widget.initialTab == 'find'; _prioritizeFind = widget.initialTab == 'find';
if (_prioritizeFind) { if (_prioritizeFind) {
_bloc.add(LoadFindFirstEvent()); _bloc.add(LoadFindFirstEvent());
@@ -37,11 +36,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
_bloc.add(LoadShiftsEvent()); _bloc.add(LoadShiftsEvent());
} }
if (_activeTab == 'history') { if (_activeTab == 'history') {
print('ShiftsPage init: loading history tab');
_bloc.add(LoadHistoryShiftsEvent()); _bloc.add(LoadHistoryShiftsEvent());
} }
if (_activeTab == 'find') { if (_activeTab == 'find') {
print('ShiftsPage init: entering find tab (not loaded yet)');
if (!_prioritizeFind) { if (!_prioritizeFind) {
_bloc.add(LoadAvailableShiftsEvent()); _bloc.add(LoadAvailableShiftsEvent());
} }

View File

@@ -1,13 +0,0 @@
import 'package:flutter/material.dart';
import 'package:design_system/design_system.dart';
class AppColors {
static const Color krowBlue = UiColors.primary;
static const Color krowYellow = UiColors.accent;
static const Color krowCharcoal = UiColors.textPrimary;
static const Color krowMuted = UiColors.textSecondary;
static const Color krowBorder = UiColors.border;
static const Color krowBackground = UiColors.background;
static const Color white = UiColors.white;
static const Color black = UiColors.black;
}

View File

@@ -1,6 +1,5 @@
import 'package:design_system/design_system.dart'; import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../styles/shifts_styles.dart';
class EmptyStateView extends StatelessWidget { class EmptyStateView extends StatelessWidget {
final IconData icon; final IconData icon;

View File

@@ -10,10 +10,7 @@ import '../shared/empty_state_view.dart';
class FindShiftsTab extends StatefulWidget { class FindShiftsTab extends StatefulWidget {
final List<Shift> availableJobs; final List<Shift> availableJobs;
const FindShiftsTab({ const FindShiftsTab({super.key, required this.availableJobs});
super.key,
required this.availableJobs,
});
@override @override
State<FindShiftsTab> createState() => _FindShiftsTabState(); State<FindShiftsTab> createState() => _FindShiftsTabState();
@@ -42,7 +39,9 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
child: Text( child: Text(
label, label,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: (isSelected ? UiTypography.footnote2m.white : UiTypography.footnote2m.textSecondary), style: (isSelected
? UiTypography.footnote2m.white
: UiTypography.footnote2m.textSecondary),
), ),
), ),
); );
@@ -86,13 +85,15 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
Expanded( Expanded(
child: Container( child: Container(
height: 48, height: 48,
padding: const EdgeInsets.symmetric(horizontal: UiConstants.space3), padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: UiColors.background, color: UiColors.background,
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(
border: Border.all( UiConstants.radiusBase,
color: UiColors.border,
), ),
border: Border.all(color: UiColors.border),
), ),
child: Row( child: Row(
children: [ children: [
@@ -123,10 +124,10 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
width: 48, width: 48,
decoration: BoxDecoration( decoration: BoxDecoration(
color: UiColors.white, color: UiColors.white,
borderRadius: BorderRadius.circular(UiConstants.radiusBase), borderRadius: BorderRadius.circular(
border: Border.all( UiConstants.radiusBase,
color: UiColors.border,
), ),
border: Border.all(color: UiColors.border),
), ),
child: const Icon( child: const Icon(
UiIcons.filter, UiIcons.filter,
@@ -164,20 +165,27 @@ class _FindShiftsTabState extends State<FindShiftsTab> {
subtitle: "Check back later", subtitle: "Check back later",
) )
: SingleChildScrollView( : SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: UiConstants.space5), padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space5,
),
child: Column( child: Column(
children: [ children: [
const SizedBox(height: UiConstants.space5), const SizedBox(height: UiConstants.space5),
...filteredJobs.map( ...filteredJobs.map(
(shift) => Padding( (shift) => Padding(
padding: const EdgeInsets.only(bottom: UiConstants.space3), padding: const EdgeInsets.only(
bottom: UiConstants.space3,
),
child: MyShiftCard( child: MyShiftCard(
shift: shift, shift: shift,
onAccept: () { onAccept: () {
context.read<ShiftsBloc>().add(AcceptShiftEvent(shift.id)); context.read<ShiftsBloc>().add(
AcceptShiftEvent(shift.id),
);
UiSnackbar.show( UiSnackbar.show(
context, context,
message: "Shift application submitted!", // Todo: Localization message:
"Shift application submitted!", // Todo: Localization
type: UiSnackbarType.success, type: UiSnackbarType.success,
); );
}, },

View File

@@ -27,6 +27,8 @@ dependencies:
path: ../../../data_connect path: ../../../data_connect
core_localization: core_localization:
path: ../../../core_localization path: ../../../core_localization
firebase_auth: ^6.1.4
firebase_data_connect: ^0.2.2+2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: