refactor: replace model with entity for shift and update imports
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
import 'package:staff_home/src/domain/repositories/home_repository.dart';
|
||||
import 'package:staff_home/src/data/services/mock_service.dart';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
|
||||
class MockService {
|
||||
static final Shift _sampleShift1 = Shift(
|
||||
@@ -74,5 +74,3 @@ class MockService {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
}
|
||||
}
|
||||
|
||||
final mockService = MockService();
|
||||
|
||||
@@ -1,29 +1,10 @@
|
||||
class Shift {
|
||||
final String id;
|
||||
final String title;
|
||||
final String clientName;
|
||||
final String? logoUrl;
|
||||
final double hourlyRate;
|
||||
final String location;
|
||||
final String? locationAddress;
|
||||
final String date;
|
||||
final String startTime;
|
||||
final String endTime;
|
||||
final String createdDate;
|
||||
final bool? tipsAvailable;
|
||||
final bool? travelTime;
|
||||
final bool? mealProvided;
|
||||
final bool? parkingAvailable;
|
||||
final bool? gasCompensation;
|
||||
final String? description;
|
||||
final String? instructions;
|
||||
final List<ShiftManager>? managers;
|
||||
final double? latitude;
|
||||
final double? longitude;
|
||||
final String? status;
|
||||
final int? durationDays;
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
Shift({
|
||||
/// Entity representing a shift for the staff home screen.
|
||||
///
|
||||
/// This entity aggregates essential shift details needed for display cards.
|
||||
class Shift extends Equatable {
|
||||
const Shift({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.clientName,
|
||||
@@ -48,12 +29,66 @@ class Shift {
|
||||
this.status,
|
||||
this.durationDays,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final String title;
|
||||
final String clientName;
|
||||
final String? logoUrl;
|
||||
final double hourlyRate;
|
||||
final String location;
|
||||
final String? locationAddress;
|
||||
final String date;
|
||||
final String startTime;
|
||||
final String endTime;
|
||||
final String createdDate;
|
||||
final bool? tipsAvailable;
|
||||
final bool? travelTime;
|
||||
final bool? mealProvided;
|
||||
final bool? parkingAvailable;
|
||||
final bool? gasCompensation;
|
||||
final String? description;
|
||||
final String? instructions;
|
||||
final List<ShiftManager>? managers;
|
||||
final double? latitude;
|
||||
final double? longitude;
|
||||
final String? status;
|
||||
final int? durationDays;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
title,
|
||||
clientName,
|
||||
logoUrl,
|
||||
hourlyRate,
|
||||
location,
|
||||
locationAddress,
|
||||
date,
|
||||
startTime,
|
||||
endTime,
|
||||
createdDate,
|
||||
tipsAvailable,
|
||||
travelTime,
|
||||
mealProvided,
|
||||
parkingAvailable,
|
||||
gasCompensation,
|
||||
description,
|
||||
instructions,
|
||||
managers,
|
||||
latitude,
|
||||
longitude,
|
||||
status,
|
||||
durationDays,
|
||||
];
|
||||
}
|
||||
|
||||
class ShiftManager {
|
||||
class ShiftManager extends Equatable {
|
||||
const ShiftManager({required this.name, required this.phone, this.avatar});
|
||||
|
||||
final String name;
|
||||
final String phone;
|
||||
final String? avatar;
|
||||
|
||||
ShiftManager({required this.name, required this.phone, this.avatar});
|
||||
@override
|
||||
List<Object?> get props => [name, phone, avatar];
|
||||
}
|
||||
@@ -1,7 +1,17 @@
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
|
||||
/// Repository interface for home screen data operations.
|
||||
///
|
||||
/// This interface defines the contract for fetching shift data
|
||||
/// displayed on the worker home screen. Implementations should
|
||||
/// handle data retrieval from appropriate data sources.
|
||||
abstract class HomeRepository {
|
||||
/// Retrieves the list of shifts scheduled for today.
|
||||
Future<List<Shift>> getTodayShifts();
|
||||
|
||||
/// Retrieves the list of shifts scheduled for tomorrow.
|
||||
Future<List<Shift>> getTomorrowShifts();
|
||||
|
||||
/// Retrieves shifts recommended for the worker based on their profile.
|
||||
Future<List<Shift>> getRecommendedShifts();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
import 'package:staff_home/src/domain/repositories/home_repository.dart';
|
||||
|
||||
/// Use case for fetching all shifts displayed on the home screen.
|
||||
///
|
||||
/// This use case aggregates shift data from multiple time periods
|
||||
/// (today, tomorrow, and recommended) into a single response.
|
||||
class GetHomeShifts {
|
||||
final HomeRepository repository;
|
||||
|
||||
GetHomeShifts(this.repository);
|
||||
|
||||
/// Executes the use case to fetch all home screen shift data.
|
||||
///
|
||||
/// Returns a [HomeShifts] object containing today's shifts,
|
||||
/// tomorrow's shifts, and recommended shifts.
|
||||
Future<HomeShifts> call() async {
|
||||
final today = await repository.getTodayShifts();
|
||||
final tomorrow = await repository.getTomorrowShifts();
|
||||
@@ -18,6 +26,9 @@ class GetHomeShifts {
|
||||
}
|
||||
}
|
||||
|
||||
/// Data transfer object containing all shifts for the home screen.
|
||||
///
|
||||
/// Groups shifts by time period for easy presentation layer consumption.
|
||||
class HomeShifts {
|
||||
final List<Shift> today;
|
||||
final List<Shift> tomorrow;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
import 'package:staff_home/src/domain/usecases/get_home_shifts.dart';
|
||||
import 'package:staff_home/src/domain/repositories/home_repository.dart';
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ class HomeState extends Equatable {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
status,
|
||||
todayShifts,
|
||||
tomorrowShifts,
|
||||
recommendedShifts,
|
||||
autoMatchEnabled,
|
||||
isProfileComplete,
|
||||
errorMessage,
|
||||
];
|
||||
status,
|
||||
todayShifts,
|
||||
tomorrowShifts,
|
||||
recommendedShifts,
|
||||
autoMatchEnabled,
|
||||
isProfileComplete,
|
||||
errorMessage,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
import 'package:staff_home/src/presentation/blocs/home_cubit.dart';
|
||||
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
||||
@@ -18,8 +19,13 @@ import 'package:staff_home/src/presentation/widgets/worker/auto_match_toggle.dar
|
||||
import 'package:staff_home/src/presentation/widgets/worker/benefits_widget.dart';
|
||||
import 'package:staff_home/src/presentation/widgets/worker/improve_yourself_widget.dart';
|
||||
import 'package:staff_home/src/presentation/widgets/worker/more_ways_widget.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
/// The home page for the staff worker application.
|
||||
///
|
||||
/// This page displays the worker's dashboard including today's shifts,
|
||||
/// tomorrow's shifts, recommended shifts, benefits, and other relevant
|
||||
/// information. It follows Clean Architecture principles with state
|
||||
/// managed by [HomeCubit].
|
||||
class WorkerHomePage extends StatelessWidget {
|
||||
const WorkerHomePage({super.key});
|
||||
|
||||
@@ -34,7 +40,7 @@ class WorkerHomePage extends StatelessWidget {
|
||||
return BlocProvider(
|
||||
create: (_) => Modular.get<HomeCubit>()..loadShifts(),
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.krowBackground,
|
||||
backgroundColor: UiColors.background,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(bottom: 100),
|
||||
@@ -76,13 +82,15 @@ class WorkerHomePage extends StatelessWidget {
|
||||
// Auto Match Toggle
|
||||
BlocBuilder<HomeCubit, HomeState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.autoMatchEnabled != current.autoMatchEnabled,
|
||||
previous.autoMatchEnabled !=
|
||||
current.autoMatchEnabled,
|
||||
builder: (context, state) {
|
||||
return AutoMatchToggle(
|
||||
enabled: state.autoMatchEnabled,
|
||||
onToggle: (val) => context
|
||||
.read<HomeCubit>()
|
||||
.toggleAutoMatch(val),
|
||||
onToggle: (val) => BlocProvider.of<HomeCubit>(
|
||||
context,
|
||||
listen: false,
|
||||
).toggleAutoMatch(val),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -176,9 +184,7 @@ class WorkerHomePage extends StatelessWidget {
|
||||
final shifts = state.tomorrowShifts;
|
||||
return Column(
|
||||
children: [
|
||||
SectionHeader(
|
||||
title: sectionsI18n.tomorrow,
|
||||
),
|
||||
SectionHeader(title: sectionsI18n.tomorrow),
|
||||
if (shifts.isEmpty)
|
||||
EmptyStateWidget(
|
||||
message: emptyI18n.no_shifts_tomorrow,
|
||||
@@ -252,4 +258,4 @@ class WorkerHomePage extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
class EmptyStateWidget extends StatelessWidget {
|
||||
final String message;
|
||||
@@ -27,7 +28,10 @@ class EmptyStateWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
message,
|
||||
style: const TextStyle(color: AppColors.krowMuted, fontSize: 14),
|
||||
style: const TextStyle(
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
if (actionLink != null)
|
||||
GestureDetector(
|
||||
@@ -37,7 +41,7 @@ class EmptyStateWidget extends StatelessWidget {
|
||||
child: Text(
|
||||
actionLink!,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
||||
|
||||
@@ -24,16 +25,16 @@ class HomeHeader extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: AppColors.krowBlue.withValues(alpha: 0.2),
|
||||
color: UiColors.primary.withValues(alpha: 0.2),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: CircleAvatar(
|
||||
backgroundColor: AppColors.krowBlue.withValues(alpha: 0.1),
|
||||
backgroundColor: UiColors.primary.withValues(alpha: 0.1),
|
||||
child: const Text(
|
||||
'K',
|
||||
style: TextStyle(
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@@ -46,14 +47,14 @@ class HomeHeader extends StatelessWidget {
|
||||
Text(
|
||||
headerI18n.welcome_back,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
headerI18n.user_name_placeholder,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -115,7 +116,7 @@ class HomeHeader extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Icon(icon, color: AppColors.krowMuted, size: 20),
|
||||
child: Icon(icon, color: UiColors.mutedForeground, size: 20),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
import 'package:staff_home/src/presentation/navigation/home_navigator.dart';
|
||||
|
||||
@@ -53,7 +54,7 @@ class PendingPaymentCard extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -61,7 +62,7 @@ class PendingPaymentCard extends StatelessWidget {
|
||||
pendingI18n.subtitle,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
class PlaceholderBanner extends StatelessWidget {
|
||||
final String title;
|
||||
@@ -48,14 +49,14 @@ class PlaceholderBanner extends StatelessWidget {
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
class QuickActionItem extends StatelessWidget {
|
||||
final IconData icon;
|
||||
@@ -36,7 +36,7 @@ class QuickActionItem extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Icon(icon, color: AppColors.krowBlue, size: 24),
|
||||
child: Icon(icon, color: UiColors.primary, size: 24),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
@@ -44,7 +44,7 @@ class QuickActionItem extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
|
||||
class RecommendedShiftCard extends StatelessWidget {
|
||||
@@ -19,9 +20,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
recI18n.applied_for(title: shift.title),
|
||||
),
|
||||
content: Text(recI18n.applied_for(title: shift.title)),
|
||||
backgroundColor: Colors.green,
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
@@ -33,7 +32,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: AppColors.krowBorder),
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.02),
|
||||
@@ -108,7 +107,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -119,7 +118,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -132,14 +131,14 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
shift.clientName,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'\$${shift.hourlyRate.toStringAsFixed(0)}/hr • ${duration}h',
|
||||
style: const TextStyle(
|
||||
fontSize: 10,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -155,21 +154,21 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
const Icon(
|
||||
LucideIcons.calendar,
|
||||
size: 14,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
recI18n.today,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Icon(
|
||||
LucideIcons.clock,
|
||||
size: 14,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -179,7 +178,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -190,7 +189,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
const Icon(
|
||||
LucideIcons.mapPin,
|
||||
size: 14,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(
|
||||
@@ -198,7 +197,7 @@ class RecommendedShiftCard extends StatelessWidget {
|
||||
shift.locationAddress ?? shift.location,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
|
||||
import 'package:design_system/design_system.dart';
|
||||
|
||||
class SectionHeader extends StatelessWidget {
|
||||
final String title;
|
||||
@@ -26,7 +27,7 @@ class SectionHeader extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
),
|
||||
if (action != null)
|
||||
@@ -38,7 +39,7 @@ class SectionHeader extends StatelessWidget {
|
||||
Text(
|
||||
action!,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
@@ -46,7 +47,7 @@ class SectionHeader extends StatelessWidget {
|
||||
const Icon(
|
||||
LucideIcons.chevronRight,
|
||||
size: 16,
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -55,10 +56,10 @@ class SectionHeader extends StatelessWidget {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.krowBlue.withValues(alpha: 0.08),
|
||||
color: UiColors.primary.withValues(alpha: 0.08),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: AppColors.krowBlue.withValues(alpha: 0.2),
|
||||
color: UiColors.primary.withValues(alpha: 0.2),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
@@ -66,7 +67,7 @@ class SectionHeader extends StatelessWidget {
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,8 +3,8 @@ import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:staff_home/src/domain/models/shift.dart';
|
||||
import 'package:staff_home/src/theme.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:staff_home/src/domain/entities/shift.dart';
|
||||
|
||||
class ShiftCard extends StatefulWidget {
|
||||
final Shift shift;
|
||||
@@ -65,7 +65,6 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.compact) {
|
||||
@@ -85,7 +84,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: AppColors.krowBorder),
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
@@ -102,7 +101,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColors.krowBorder),
|
||||
border: Border.all(color: UiColors.border),
|
||||
),
|
||||
child: widget.shift.logoUrl != null
|
||||
? ClipRRect(
|
||||
@@ -114,7 +113,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
)
|
||||
: const Icon(
|
||||
LucideIcons.building2,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -130,7 +129,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
widget.shift.title,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -141,7 +140,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
children: const [
|
||||
TextSpan(
|
||||
@@ -159,7 +158,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
Text(
|
||||
widget.shift.clientName,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 13,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -168,7 +167,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
Text(
|
||||
'${_formatTime(widget.shift.startTime)} • ${widget.shift.location}',
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
@@ -186,7 +185,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: AppColors.krowBorder),
|
||||
border: Border.all(color: UiColors.border),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
@@ -211,7 +210,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColors.krowBorder),
|
||||
border: Border.all(color: UiColors.border),
|
||||
),
|
||||
child: widget.shift.logoUrl != null
|
||||
? ClipRRect(
|
||||
@@ -224,7 +223,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
: const Icon(
|
||||
LucideIcons.building2,
|
||||
size: 28,
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
@@ -233,7 +232,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
vertical: 6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.krowBlue,
|
||||
color: UiColors.primary,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
@@ -263,13 +262,13 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
widget.shift.clientName,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
@@ -282,7 +281,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
color: AppColors.krowCharcoal,
|
||||
color: UiColors.foreground,
|
||||
),
|
||||
children: const [
|
||||
TextSpan(
|
||||
@@ -305,14 +304,14 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
const Icon(
|
||||
LucideIcons.mapPin,
|
||||
size: 16,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.shift.location,
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 14,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -322,13 +321,13 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
const Icon(
|
||||
LucideIcons.calendar,
|
||||
size: 16,
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'${_formatDate(widget.shift.date)}, ${_formatTime(widget.shift.startTime)}',
|
||||
style: const TextStyle(
|
||||
color: AppColors.krowMuted,
|
||||
color: UiColors.mutedForeground,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
@@ -344,8 +343,8 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
_buildTag(
|
||||
LucideIcons.zap,
|
||||
'Immediate start',
|
||||
AppColors.krowYellow.withValues(alpha: 0.3),
|
||||
AppColors.krowCharcoal,
|
||||
UiColors.accent.withValues(alpha: 0.3),
|
||||
UiColors.foreground,
|
||||
),
|
||||
_buildTag(
|
||||
LucideIcons.timer,
|
||||
@@ -373,7 +372,7 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
child: ElevatedButton(
|
||||
onPressed: widget.onApply,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.krowCharcoal,
|
||||
backgroundColor: UiColors.foreground,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -439,6 +438,4 @@ class _ShiftCardState extends State<ShiftCard> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
||||
boxShadow: widget.enabled
|
||||
? [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF0032A0).withOpacity(0.3),
|
||||
color: const Color(0xFF0032A0).withValues(alpha: 0.3),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
@@ -58,8 +58,8 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.enabled
|
||||
? Colors.white.withOpacity(0.2)
|
||||
: const Color(0xFF0032A0).withOpacity(0.1),
|
||||
? Colors.white.withValues(alpha: 0.2)
|
||||
: const Color(0xFF0032A0).withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Icon(
|
||||
@@ -100,7 +100,7 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
||||
value: widget.enabled,
|
||||
onChanged: widget.onToggle,
|
||||
activeThumbColor: Colors.white,
|
||||
activeTrackColor: Colors.white.withOpacity(0.3),
|
||||
activeTrackColor: Colors.white.withValues(alpha: 0.3),
|
||||
inactiveThumbColor: Colors.white,
|
||||
inactiveTrackColor: Colors.grey.shade300,
|
||||
),
|
||||
@@ -115,7 +115,7 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
height: 1,
|
||||
color: Colors.white.withOpacity(0.2),
|
||||
color: Colors.white.withValues(alpha: 0.2),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
@@ -150,7 +150,7 @@ class _AutoMatchToggleState extends State<AutoMatchToggle>
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.2),
|
||||
color: Colors.white.withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
|
||||
@@ -6,12 +6,23 @@ import 'package:staff_home/src/domain/repositories/home_repository.dart';
|
||||
import 'package:staff_home/src/presentation/blocs/home_cubit.dart';
|
||||
import 'package:staff_home/src/presentation/pages/worker_home_page.dart';
|
||||
|
||||
/// The module for the staff home feature.
|
||||
///
|
||||
/// This module provides dependency injection bindings for the home feature
|
||||
/// following Clean Architecture principles. It injects the repository
|
||||
/// implementation and state management components.
|
||||
class StaffHomeModule extends Module {
|
||||
@override
|
||||
void binds(Injector i) {
|
||||
// Data layer - Mock service (will be replaced with real implementation)
|
||||
i.addLazySingleton<MockService>(MockService.new);
|
||||
|
||||
// Repository
|
||||
i.addLazySingleton<HomeRepository>(
|
||||
() => HomeRepositoryImpl(mockService),
|
||||
() => HomeRepositoryImpl(i.get<MockService>()),
|
||||
);
|
||||
|
||||
// Presentation layer - Cubit
|
||||
i.addSingleton(HomeCubit.new);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
class AppColors {
|
||||
static const Color krowBlue = Color(0xFF0A39DF);
|
||||
static const Color krowYellow = Color(0xFFFFED4A);
|
||||
static const Color krowCharcoal = Color(0xFF121826);
|
||||
static const Color krowMuted = Color(0xFF6A7382);
|
||||
static const Color krowBorder = Color(0xFFE3E6E9);
|
||||
static const Color krowBackground = Color(0xFFFAFBFC);
|
||||
|
||||
static const Color white = Colors.white;
|
||||
static const Color black = Colors.black;
|
||||
|
||||
// helpers used by prototype (withValues extension in prototype); keep simple aliases
|
||||
static Color withAlpha(Color c, double alpha) => c.withOpacity(alpha);
|
||||
}
|
||||
|
||||
class AppTheme {
|
||||
static ThemeData get lightTheme {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
scaffoldBackgroundColor: AppColors.krowBackground,
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: AppColors.krowBlue,
|
||||
primary: AppColors.krowBlue,
|
||||
secondary: AppColors.krowYellow,
|
||||
surface: AppColors.white,
|
||||
background: AppColors.krowBackground,
|
||||
),
|
||||
textTheme: GoogleFonts.instrumentSansTextTheme().apply(
|
||||
bodyColor: AppColors.krowCharcoal,
|
||||
displayColor: AppColors.krowCharcoal,
|
||||
),
|
||||
appBarTheme: const AppBarTheme(
|
||||
backgroundColor: AppColors.krowBackground,
|
||||
elevation: 0,
|
||||
iconTheme: IconThemeData(color: AppColors.krowCharcoal),
|
||||
titleTextStyle: TextStyle(
|
||||
color: AppColors.krowCharcoal,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension ColorWithValues on Color {
|
||||
Color withValues({double alpha = 1.0}) => withOpacity(alpha);
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
/// Staff Home Feature Library
|
||||
///
|
||||
/// This library exports the public API for the staff home feature,
|
||||
/// following Clean Architecture principles. Only the module is exported
|
||||
/// as it contains all necessary bindings and routes for integration.
|
||||
library;
|
||||
|
||||
export 'src/staff_home_module.dart';
|
||||
|
||||
Reference in New Issue
Block a user