Add explicit types and improve type safety across codebase
This commit adds explicit type annotations to variables, function parameters, and return types throughout the codebase, particularly in widget trees, Bloc logic, and repository implementations. The changes improve code readability, maintainability, and type safety, and align with Dart best practices. No business logic was changed.
This commit is contained in:
@@ -18,7 +18,7 @@ export 'src/presentation/navigation/client_home_navigator.dart';
|
||||
/// including repositories, use cases, and BLoCs.
|
||||
class ClientHomeModule extends Module {
|
||||
@override
|
||||
List<Module> get imports => [DataConnectModule()];
|
||||
List<Module> get imports => <Module>[DataConnectModule()];
|
||||
|
||||
@override
|
||||
void binds(Injector i) {
|
||||
@@ -41,7 +41,7 @@ class ClientHomeModule extends Module {
|
||||
}
|
||||
|
||||
@override
|
||||
void routes(r) {
|
||||
void routes(RouteManager r) {
|
||||
r.child('/', child: (_) => const ClientHomePage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class HomeRepositoryImpl implements HomeRepositoryInterface {
|
||||
|
||||
@override
|
||||
UserSessionData getUserSessionData() {
|
||||
final (businessName, photoUrl) = _mock.getUserSession();
|
||||
final (String businessName, String? photoUrl) = _mock.getUserSession();
|
||||
return UserSessionData(
|
||||
businessName: businessName,
|
||||
photoUrl: photoUrl,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:client_home/src/domain/repositories/home_repository_interface.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_domain/src/entities/home/home_dashboard_data.dart';
|
||||
import '../../domain/usecases/get_dashboard_data_usecase.dart';
|
||||
import '../../domain/usecases/get_user_session_data_usecase.dart';
|
||||
import 'client_home_event.dart';
|
||||
@@ -29,10 +31,10 @@ class ClientHomeBloc extends Bloc<ClientHomeEvent, ClientHomeState> {
|
||||
emit(state.copyWith(status: ClientHomeStatus.loading));
|
||||
try {
|
||||
// Get session data
|
||||
final sessionData = _getUserSessionDataUseCase();
|
||||
final UserSessionData sessionData = _getUserSessionDataUseCase();
|
||||
|
||||
// Get dashboard data
|
||||
final data = await _getDashboardDataUseCase();
|
||||
final HomeDashboardData data = await _getDashboardDataUseCase();
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
@@ -63,7 +65,7 @@ class ClientHomeBloc extends Bloc<ClientHomeEvent, ClientHomeState> {
|
||||
ClientHomeWidgetVisibilityToggled event,
|
||||
Emitter<ClientHomeState> emit,
|
||||
) {
|
||||
final newVisibility = Map<String, bool>.from(state.widgetVisibility);
|
||||
final Map<String, bool> newVisibility = Map<String, bool>.from(state.widgetVisibility);
|
||||
newVisibility[event.widgetId] = !(newVisibility[event.widgetId] ?? true);
|
||||
emit(state.copyWith(widgetVisibility: newVisibility));
|
||||
}
|
||||
@@ -72,14 +74,14 @@ class ClientHomeBloc extends Bloc<ClientHomeEvent, ClientHomeState> {
|
||||
ClientHomeWidgetReordered event,
|
||||
Emitter<ClientHomeState> emit,
|
||||
) {
|
||||
final newList = List<String>.from(state.widgetOrder);
|
||||
final List<String> newList = List<String>.from(state.widgetOrder);
|
||||
int oldIndex = event.oldIndex;
|
||||
int newIndex = event.newIndex;
|
||||
|
||||
if (oldIndex < newIndex) {
|
||||
newIndex -= 1;
|
||||
}
|
||||
final item = newList.removeAt(oldIndex);
|
||||
final String item = newList.removeAt(oldIndex);
|
||||
newList.insert(newIndex, item);
|
||||
|
||||
emit(state.copyWith(widgetOrder: newList));
|
||||
@@ -91,14 +93,14 @@ class ClientHomeBloc extends Bloc<ClientHomeEvent, ClientHomeState> {
|
||||
) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
widgetOrder: const [
|
||||
widgetOrder: const <String>[
|
||||
'actions',
|
||||
'reorder',
|
||||
'coverage',
|
||||
'spending',
|
||||
'liveActivity',
|
||||
],
|
||||
widgetVisibility: const {
|
||||
widgetVisibility: const <String, bool>{
|
||||
'actions': true,
|
||||
'reorder': true,
|
||||
'coverage': true,
|
||||
|
||||
@@ -4,7 +4,7 @@ abstract class ClientHomeEvent extends Equatable {
|
||||
const ClientHomeEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
List<Object?> get props => <Object?>[];
|
||||
}
|
||||
|
||||
class ClientHomeStarted extends ClientHomeEvent {}
|
||||
@@ -16,7 +16,7 @@ class ClientHomeWidgetVisibilityToggled extends ClientHomeEvent {
|
||||
const ClientHomeWidgetVisibilityToggled(this.widgetId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [widgetId];
|
||||
List<Object?> get props => <Object?>[widgetId];
|
||||
}
|
||||
|
||||
class ClientHomeWidgetReordered extends ClientHomeEvent {
|
||||
@@ -25,7 +25,7 @@ class ClientHomeWidgetReordered extends ClientHomeEvent {
|
||||
const ClientHomeWidgetReordered(this.oldIndex, this.newIndex);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [oldIndex, newIndex];
|
||||
List<Object?> get props => <Object?>[oldIndex, newIndex];
|
||||
}
|
||||
|
||||
class ClientHomeLayoutReset extends ClientHomeEvent {}
|
||||
|
||||
@@ -17,10 +17,10 @@ class ClientHomeState extends Equatable {
|
||||
|
||||
const ClientHomeState({
|
||||
this.status = ClientHomeStatus.initial,
|
||||
this.widgetOrder = const [
|
||||
this.widgetOrder = const <String>[
|
||||
'actions',
|
||||
],
|
||||
this.widgetVisibility = const {
|
||||
this.widgetVisibility = const <String, bool>{
|
||||
'actions': true,
|
||||
},
|
||||
this.isEditMode = false,
|
||||
@@ -60,7 +60,7 @@ class ClientHomeState extends Equatable {
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
List<Object?> get props => <Object?>[
|
||||
status,
|
||||
widgetOrder,
|
||||
widgetVisibility,
|
||||
|
||||
@@ -31,10 +31,10 @@ class ClientHomeSheets {
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
builder: (BuildContext context) {
|
||||
return ShiftOrderFormSheet(
|
||||
initialData: initialData,
|
||||
onSubmit: (data) {
|
||||
onSubmit: (Map<String, dynamic> data) {
|
||||
Navigator.pop(context);
|
||||
onSubmit(data);
|
||||
},
|
||||
|
||||
@@ -21,20 +21,20 @@ class ClientHomePage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = t.client_home;
|
||||
final TranslationsClientHomeEn i18n = t.client_home;
|
||||
|
||||
return BlocProvider<ClientHomeBloc>(
|
||||
create: (context) =>
|
||||
create: (BuildContext context) =>
|
||||
Modular.get<ClientHomeBloc>()..add(ClientHomeStarted()),
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
ClientHomeHeader(i18n: i18n),
|
||||
ClientHomeEditBanner(i18n: i18n),
|
||||
Flexible(
|
||||
child: BlocBuilder<ClientHomeBloc, ClientHomeState>(
|
||||
builder: (context, state) {
|
||||
builder: (BuildContext context, ClientHomeState state) {
|
||||
if (state.isEditMode) {
|
||||
return _buildEditModeList(context, state);
|
||||
}
|
||||
@@ -58,12 +58,12 @@ class ClientHomePage extends StatelessWidget {
|
||||
UiConstants.space4,
|
||||
100,
|
||||
),
|
||||
onReorder: (oldIndex, newIndex) {
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
BlocProvider.of<ClientHomeBloc>(context).add(
|
||||
ClientHomeWidgetReordered(oldIndex, newIndex),
|
||||
);
|
||||
},
|
||||
children: state.widgetOrder.map((id) {
|
||||
children: state.widgetOrder.map((String id) {
|
||||
return Container(
|
||||
key: ValueKey(id),
|
||||
margin: const EdgeInsets.only(bottom: UiConstants.space4),
|
||||
@@ -86,7 +86,7 @@ class ClientHomePage extends StatelessWidget {
|
||||
UiConstants.space4,
|
||||
100,
|
||||
),
|
||||
children: state.widgetOrder.map((id) {
|
||||
children: state.widgetOrder.map((String id) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: UiConstants.space4),
|
||||
child: DashboardWidgetBuilder(
|
||||
|
||||
@@ -20,10 +20,10 @@ class ActionsWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Check if client_home exists in t
|
||||
final i18n = t.client_home.actions;
|
||||
final TranslationsClientHomeActionsEn i18n = t.client_home.actions;
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: _ActionCard(
|
||||
title: i18n.rapid,
|
||||
@@ -96,7 +96,7 @@ class _ActionCard extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
|
||||
@@ -22,8 +22,8 @@ class ClientHomeEditBanner extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ClientHomeBloc, ClientHomeState>(
|
||||
buildWhen: (prev, curr) => prev.isEditMode != curr.isEditMode,
|
||||
builder: (context, state) {
|
||||
buildWhen: (ClientHomeState prev, ClientHomeState curr) => prev.isEditMode != curr.isEditMode,
|
||||
builder: (BuildContext context, ClientHomeState state) {
|
||||
return AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
height: state.isEditMode ? 76 : 0,
|
||||
@@ -40,13 +40,13 @@ class ClientHomeEditBanner extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
const Icon(UiIcons.edit, size: 16, color: UiColors.primary),
|
||||
const SizedBox(width: UiConstants.space2),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
i18n.dashboard.edit_mode_active,
|
||||
style: UiTypography.footnote1b.copyWith(
|
||||
|
||||
@@ -25,10 +25,10 @@ class ClientHomeHeader extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ClientHomeBloc, ClientHomeState>(
|
||||
builder: (context, state) {
|
||||
final businessName = state.businessName;
|
||||
final photoUrl = state.photoUrl;
|
||||
final avatarLetter = businessName.trim().isNotEmpty
|
||||
builder: (BuildContext context, ClientHomeState state) {
|
||||
final String businessName = state.businessName;
|
||||
final String? photoUrl = state.photoUrl;
|
||||
final String avatarLetter = businessName.trim().isNotEmpty
|
||||
? businessName.trim()[0].toUpperCase()
|
||||
: 'C';
|
||||
|
||||
@@ -41,9 +41,9 @@ class ClientHomeHeader extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
@@ -73,7 +73,7 @@ class ClientHomeHeader extends StatelessWidget {
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
i18n.dashboard.welcome_back,
|
||||
style: UiTypography.footnote2r.textSecondary,
|
||||
|
||||
@@ -23,32 +23,32 @@ class CoverageDashboard extends StatelessWidget {
|
||||
double todayCost = 0;
|
||||
|
||||
for (final s in shifts) {
|
||||
final needed = s['workersNeeded'] as int? ?? 0;
|
||||
final confirmed = s['filled'] as int? ?? 0;
|
||||
final rate = s['hourlyRate'] as double? ?? 20.0;
|
||||
final int needed = s['workersNeeded'] as int? ?? 0;
|
||||
final int confirmed = s['filled'] as int? ?? 0;
|
||||
final double rate = s['hourlyRate'] as double? ?? 20.0;
|
||||
|
||||
totalNeeded += needed;
|
||||
totalConfirmed += confirmed;
|
||||
todayCost += rate * 8 * confirmed;
|
||||
}
|
||||
|
||||
final coveragePercent = totalNeeded > 0
|
||||
final int coveragePercent = totalNeeded > 0
|
||||
? ((totalConfirmed / totalNeeded) * 100).round()
|
||||
: 100;
|
||||
final unfilledPositions = totalNeeded - totalConfirmed;
|
||||
final int unfilledPositions = totalNeeded - totalConfirmed;
|
||||
|
||||
final checkedInCount = applications
|
||||
final int checkedInCount = applications
|
||||
.where((a) => (a as Map)['checkInTime'] != null)
|
||||
.length;
|
||||
final lateWorkersCount = applications
|
||||
final int lateWorkersCount = applications
|
||||
.where((a) => (a as Map)['status'] == 'LATE')
|
||||
.length;
|
||||
|
||||
final isCoverageGood = coveragePercent >= 90;
|
||||
final coverageBadgeColor = isCoverageGood
|
||||
final bool isCoverageGood = coveragePercent >= 90;
|
||||
final Color coverageBadgeColor = isCoverageGood
|
||||
? const Color(0xFFD1FAE5) // TODO: Use design system color if available
|
||||
: const Color(0xFFFEF3C7);
|
||||
final coverageTextColor = isCoverageGood
|
||||
final Color coverageTextColor = isCoverageGood
|
||||
? const Color(0xFF047857)
|
||||
: const Color(0xFFB45309);
|
||||
|
||||
@@ -58,7 +58,7 @@ class CoverageDashboard extends StatelessWidget {
|
||||
color: UiColors.white,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: UiColors.black.withValues(alpha: 0.02),
|
||||
blurRadius: 4,
|
||||
@@ -67,10 +67,10 @@ class CoverageDashboard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text("Today's Status", style: UiTypography.body1m.textSecondary),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
@@ -94,17 +94,17 @@ class CoverageDashboard extends StatelessWidget {
|
||||
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
_StatusCard(
|
||||
label: 'Unfilled Today',
|
||||
value: '$unfilledPositions',
|
||||
icon: UiIcons.warning,
|
||||
isWarning: unfilledPositions > 0,
|
||||
),
|
||||
if (lateWorkersCount > 0) ...[
|
||||
if (lateWorkersCount > 0) ...<Widget>[
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
_StatusCard(
|
||||
label: 'Running Late',
|
||||
@@ -119,7 +119,7 @@ class CoverageDashboard extends StatelessWidget {
|
||||
const SizedBox(width: UiConstants.space2),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
_StatusCard(
|
||||
label: 'Checked In',
|
||||
value: '$checkedInCount/$totalConfirmed',
|
||||
@@ -194,9 +194,9 @@ class _StatusCard extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Icon(icon, size: 16, color: iconColor),
|
||||
const SizedBox(width: UiConstants.space2),
|
||||
Expanded(
|
||||
|
||||
@@ -23,10 +23,10 @@ class CoverageWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"TODAY'S COVERAGE",
|
||||
style: UiTypography.footnote1b.copyWith(
|
||||
@@ -55,7 +55,7 @@ class CoverageWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space2),
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: _MetricCard(
|
||||
icon: UiIcons.target,
|
||||
@@ -114,7 +114,7 @@ class _MetricCard extends StatelessWidget {
|
||||
color: UiColors.cardViewBackground,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: UiColors.black.withValues(alpha: 0.02),
|
||||
blurRadius: 2,
|
||||
@@ -123,9 +123,9 @@ class _MetricCard extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Icon(icon, size: 14, color: iconColor),
|
||||
const SizedBox(width: 6), // 6px
|
||||
Text(
|
||||
|
||||
@@ -34,8 +34,8 @@ class DashboardWidgetBuilder extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = t.client_home.widgets;
|
||||
final widgetContent = _buildWidgetContent(context);
|
||||
final TranslationsClientHomeWidgetsEn i18n = t.client_home.widgets;
|
||||
final Widget widgetContent = _buildWidgetContent(context);
|
||||
|
||||
if (isEditMode) {
|
||||
return DraggableWidgetWrapper(
|
||||
@@ -64,11 +64,11 @@ class DashboardWidgetBuilder extends StatelessWidget {
|
||||
);
|
||||
case 'reorder':
|
||||
return ReorderWidget(
|
||||
onReorderPressed: (data) {
|
||||
onReorderPressed: (Map<String, dynamic> data) {
|
||||
ClientHomeSheets.showOrderFormSheet(
|
||||
context,
|
||||
data,
|
||||
onSubmit: (submittedData) {
|
||||
onSubmit: (Map<String, dynamic> submittedData) {
|
||||
// Handle form submission if needed
|
||||
},
|
||||
);
|
||||
|
||||
@@ -34,9 +34,9 @@ class DraggableWidgetWrapper extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: UiConstants.space2,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space2,
|
||||
@@ -48,7 +48,7 @@ class DraggableWidgetWrapper extends StatelessWidget {
|
||||
border: Border.all(color: UiColors.border),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
UiIcons.gripVertical,
|
||||
size: 14,
|
||||
|
||||
@@ -33,14 +33,14 @@ class HeaderIconButton extends StatelessWidget {
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? UiColors.primary : UiColors.white,
|
||||
borderRadius: UiConstants.radiusMd,
|
||||
boxShadow: [
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
blurRadius: 2,
|
||||
|
||||
@@ -13,18 +13,18 @@ class LiveActivityWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = t.client_home;
|
||||
final TranslationsClientHomeEn i18n = t.client_home;
|
||||
|
||||
// Mock data
|
||||
final shifts = [
|
||||
{
|
||||
final List<Map<String, Object>> shifts = <Map<String, Object>>[
|
||||
<String, Object>{
|
||||
'workersNeeded': 5,
|
||||
'filled': 4,
|
||||
'hourlyRate': 20.0,
|
||||
'status': 'OPEN',
|
||||
'date': DateTime.now().toIso8601String().split('T')[0],
|
||||
},
|
||||
{
|
||||
<String, Object>{
|
||||
'workersNeeded': 5,
|
||||
'filled': 5,
|
||||
'hourlyRate': 22.0,
|
||||
@@ -32,18 +32,18 @@ class LiveActivityWidget extends StatelessWidget {
|
||||
'date': DateTime.now().toIso8601String().split('T')[0],
|
||||
},
|
||||
];
|
||||
final applications = [
|
||||
{'status': 'CONFIRMED', 'checkInTime': '09:00'},
|
||||
{'status': 'CONFIRMED', 'checkInTime': '09:05'},
|
||||
{'status': 'CONFIRMED'},
|
||||
{'status': 'LATE'},
|
||||
final List<Map<String, String>> applications = <Map<String, String>>[
|
||||
<String, String>{'status': 'CONFIRMED', 'checkInTime': '09:00'},
|
||||
<String, String>{'status': 'CONFIRMED', 'checkInTime': '09:05'},
|
||||
<String, String>{'status': 'CONFIRMED'},
|
||||
<String, String>{'status': 'LATE'},
|
||||
];
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
i18n.widgets.live_activity.toUpperCase(),
|
||||
style: UiTypography.footnote1b.textSecondary.copyWith(
|
||||
|
||||
@@ -12,11 +12,11 @@ class ReorderWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = t.client_home.reorder;
|
||||
final TranslationsClientHomeReorderEn i18n = t.client_home.reorder;
|
||||
|
||||
// Mock recent orders
|
||||
final recentOrders = [
|
||||
{
|
||||
final List<Map<String, Object>> recentOrders = <Map<String, Object>>[
|
||||
<String, Object>{
|
||||
'title': 'Server',
|
||||
'location': 'Downtown Restaurant',
|
||||
'hourlyRate': 18.0,
|
||||
@@ -24,7 +24,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
'workers': 3,
|
||||
'type': 'One Day',
|
||||
},
|
||||
{
|
||||
<String, Object>{
|
||||
'title': 'Bartender',
|
||||
'location': 'Rooftop Bar',
|
||||
'hourlyRate': 22.0,
|
||||
@@ -32,7 +32,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
'workers': 2,
|
||||
'type': 'One Day',
|
||||
},
|
||||
{
|
||||
<String, Object>{
|
||||
'title': 'Event Staff',
|
||||
'location': 'Convention Center',
|
||||
'hourlyRate': 20.0,
|
||||
@@ -44,7 +44,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
i18n.title,
|
||||
style: UiTypography.footnote1b.textSecondary.copyWith(
|
||||
@@ -57,11 +57,11 @@ class ReorderWidget extends StatelessWidget {
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: recentOrders.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
separatorBuilder: (BuildContext context, int index) =>
|
||||
const SizedBox(width: UiConstants.space3),
|
||||
itemBuilder: (context, index) {
|
||||
final order = recentOrders[index];
|
||||
final totalCost =
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final Map<String, Object> order = recentOrders[index];
|
||||
final double totalCost =
|
||||
(order['hourlyRate'] as double) *
|
||||
(order['hours'] as int) *
|
||||
(order['workers'] as int);
|
||||
@@ -73,7 +73,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
color: UiColors.white,
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: UiColors.black.withValues(alpha: 0.02),
|
||||
blurRadius: 4,
|
||||
@@ -82,13 +82,13 @@ class ReorderWidget extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
@@ -108,7 +108,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
order['title'] as String,
|
||||
style: UiTypography.body2b,
|
||||
@@ -128,7 +128,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'\$${totalCost.toStringAsFixed(0)}',
|
||||
style: UiTypography.body1b,
|
||||
@@ -146,7 +146,7 @@ class ReorderWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: UiConstants.space3),
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
_Badge(
|
||||
icon: UiIcons.success,
|
||||
text: order['type'] as String,
|
||||
@@ -222,7 +222,7 @@ class _Badge extends StatelessWidget {
|
||||
decoration: BoxDecoration(color: bg, borderRadius: UiConstants.radiusSm),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Icon(icon, size: 10, color: bg == textColor ? UiColors.white : color),
|
||||
const SizedBox(width: UiConstants.space1),
|
||||
Text(text, style: UiTypography.footnote2b.copyWith(color: textColor)),
|
||||
|
||||
@@ -34,7 +34,7 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
|
||||
late List<Map<String, dynamic>> _positions;
|
||||
|
||||
final List<String> _roles = [
|
||||
final List<String> _roles = <String>[
|
||||
'Server',
|
||||
'Bartender',
|
||||
'Cook',
|
||||
@@ -48,11 +48,11 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
];
|
||||
|
||||
// Vendor options
|
||||
final List<Map<String, dynamic>> _vendors = [
|
||||
{
|
||||
final List<Map<String, dynamic>> _vendors = <Map<String, dynamic>>[
|
||||
<String, dynamic>{
|
||||
'id': 'v1',
|
||||
'name': 'Elite Staffing',
|
||||
'rates': {
|
||||
'rates': <String, double>{
|
||||
'Server': 25.0,
|
||||
'Bartender': 30.0,
|
||||
'Cook': 28.0,
|
||||
@@ -63,10 +63,10 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
'Event Staff': 19.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
<String, dynamic>{
|
||||
'id': 'v2',
|
||||
'name': 'Premier Workforce',
|
||||
'rates': {
|
||||
'rates': <String, double>{
|
||||
'Server': 22.0,
|
||||
'Bartender': 28.0,
|
||||
'Cook': 25.0,
|
||||
@@ -81,7 +81,7 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
|
||||
String? _selectedVendorId;
|
||||
|
||||
final List<int> _lunchBreakOptions = [0, 30, 45, 60];
|
||||
final List<int> _lunchBreakOptions = <int>[0, 30, 45, 60];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -427,7 +427,7 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
style: UiTypography.body2r.textPrimary,
|
||||
items: _vendors
|
||||
.map(
|
||||
(vendor) => DropdownMenuItem<String>(
|
||||
(Map<String, dynamic> vendor) => DropdownMenuItem<String>(
|
||||
value: vendor['id'],
|
||||
child: Text(vendor['name']),
|
||||
),
|
||||
@@ -565,7 +565,7 @@ class _ShiftOrderFormSheetState extends State<ShiftOrderFormSheet> {
|
||||
items: _roles,
|
||||
itemBuilder: (dynamic role) {
|
||||
final Map<String, dynamic>? vendor = _vendors.firstWhere(
|
||||
(v) => v['id'] == _selectedVendorId,
|
||||
(Map<String, dynamic> v) => v['id'] == _selectedVendorId,
|
||||
orElse: () => _vendors.first,
|
||||
);
|
||||
final Map<String, dynamic>? rates = vendor?['rates'] as Map<String, dynamic>?;
|
||||
|
||||
@@ -27,11 +27,11 @@ class SpendingWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final i18n = t.client_home;
|
||||
final TranslationsClientHomeEn i18n = t.client_home;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
i18n.widgets.spending.toUpperCase(),
|
||||
style: UiTypography.footnote1b.textSecondary.copyWith(
|
||||
@@ -43,12 +43,12 @@ class SpendingWidget extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(UiConstants.space3),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [UiColors.primary, Color(0xFF0830B8)],
|
||||
colors: <Color>[UiColors.primary, Color(0xFF0830B8)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
boxShadow: [
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: UiColors.primary.withValues(alpha: 0.3),
|
||||
blurRadius: 4,
|
||||
@@ -57,13 +57,13 @@ class SpendingWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
const Text(
|
||||
'This Week',
|
||||
style: TextStyle(color: Colors.white70, fontSize: 9),
|
||||
@@ -89,7 +89,7 @@ class SpendingWidget extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
const Text(
|
||||
'Next 7 Days',
|
||||
style: TextStyle(color: Colors.white70, fontSize: 9),
|
||||
@@ -122,7 +122,7 @@ class SpendingWidget extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
@@ -142,7 +142,7 @@ class SpendingWidget extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'💡 ' +
|
||||
i18n.dashboard.insight_lightbulb(amount: '180'),
|
||||
|
||||
Reference in New Issue
Block a user