feat: Integrate staff name retrieval and display in home header
This commit is contained in:
@@ -11,7 +11,6 @@ extension TimestampExt on Timestamp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class HomeRepositoryImpl implements HomeRepository {
|
class HomeRepositoryImpl implements HomeRepository {
|
||||||
HomeRepositoryImpl();
|
HomeRepositoryImpl();
|
||||||
|
|
||||||
@@ -73,6 +72,12 @@ class HomeRepositoryImpl implements HomeRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> getStaffName() async {
|
||||||
|
final session = StaffSessionStore.instance.session;
|
||||||
|
return session?.staff?.name;
|
||||||
|
}
|
||||||
|
|
||||||
// Mappers specific to Home's Domain Entity 'Shift'
|
// Mappers specific to Home's Domain Entity 'Shift'
|
||||||
// Note: Home's 'Shift' entity might differ slightly from 'StaffPayment' Shift.
|
// Note: Home's 'Shift' entity might differ slightly from 'StaffPayment' Shift.
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,7 @@ abstract class HomeRepository {
|
|||||||
|
|
||||||
/// Retrieves shifts recommended for the worker based on their profile.
|
/// Retrieves shifts recommended for the worker based on their profile.
|
||||||
Future<List<Shift>> getRecommendedShifts();
|
Future<List<Shift>> getRecommendedShifts();
|
||||||
|
|
||||||
|
/// Retrieves the current staff member's name.
|
||||||
|
Future<String?> getStaffName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ part 'home_state.dart';
|
|||||||
/// Simple Cubit to manage home page state (shifts + loading/error).
|
/// Simple Cubit to manage home page state (shifts + loading/error).
|
||||||
class HomeCubit extends Cubit<HomeState> {
|
class HomeCubit extends Cubit<HomeState> {
|
||||||
final GetHomeShifts _getHomeShifts;
|
final GetHomeShifts _getHomeShifts;
|
||||||
|
final HomeRepository _repository;
|
||||||
|
|
||||||
HomeCubit(HomeRepository repository)
|
HomeCubit(HomeRepository repository)
|
||||||
: _getHomeShifts = GetHomeShifts(repository),
|
: _getHomeShifts = GetHomeShifts(repository),
|
||||||
|
_repository = repository,
|
||||||
super(const HomeState.initial());
|
super(const HomeState.initial());
|
||||||
|
|
||||||
Future<void> loadShifts() async {
|
Future<void> loadShifts() async {
|
||||||
@@ -20,6 +22,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
emit(state.copyWith(status: HomeStatus.loading));
|
emit(state.copyWith(status: HomeStatus.loading));
|
||||||
try {
|
try {
|
||||||
final result = await _getHomeShifts.call();
|
final result = await _getHomeShifts.call();
|
||||||
|
final name = await _repository.getStaffName();
|
||||||
if (isClosed) return;
|
if (isClosed) return;
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
@@ -27,6 +30,7 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
todayShifts: result.today,
|
todayShifts: result.today,
|
||||||
tomorrowShifts: result.tomorrow,
|
tomorrowShifts: result.tomorrow,
|
||||||
recommendedShifts: result.recommended,
|
recommendedShifts: result.recommended,
|
||||||
|
staffName: name,
|
||||||
// Mock profile status for now, ideally fetched from a user repository
|
// Mock profile status for now, ideally fetched from a user repository
|
||||||
isProfileComplete: false,
|
isProfileComplete: false,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class HomeState extends Equatable {
|
|||||||
final List<Shift> recommendedShifts;
|
final List<Shift> recommendedShifts;
|
||||||
final bool autoMatchEnabled;
|
final bool autoMatchEnabled;
|
||||||
final bool isProfileComplete;
|
final bool isProfileComplete;
|
||||||
|
final String? staffName;
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
|
|
||||||
const HomeState({
|
const HomeState({
|
||||||
@@ -18,6 +19,7 @@ class HomeState extends Equatable {
|
|||||||
this.recommendedShifts = const [],
|
this.recommendedShifts = const [],
|
||||||
this.autoMatchEnabled = false,
|
this.autoMatchEnabled = false,
|
||||||
this.isProfileComplete = false,
|
this.isProfileComplete = false,
|
||||||
|
this.staffName,
|
||||||
this.errorMessage,
|
this.errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ class HomeState extends Equatable {
|
|||||||
List<Shift>? recommendedShifts,
|
List<Shift>? recommendedShifts,
|
||||||
bool? autoMatchEnabled,
|
bool? autoMatchEnabled,
|
||||||
bool? isProfileComplete,
|
bool? isProfileComplete,
|
||||||
|
String? staffName,
|
||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
}) {
|
}) {
|
||||||
return HomeState(
|
return HomeState(
|
||||||
@@ -39,6 +42,7 @@ class HomeState extends Equatable {
|
|||||||
recommendedShifts: recommendedShifts ?? this.recommendedShifts,
|
recommendedShifts: recommendedShifts ?? this.recommendedShifts,
|
||||||
autoMatchEnabled: autoMatchEnabled ?? this.autoMatchEnabled,
|
autoMatchEnabled: autoMatchEnabled ?? this.autoMatchEnabled,
|
||||||
isProfileComplete: isProfileComplete ?? this.isProfileComplete,
|
isProfileComplete: isProfileComplete ?? this.isProfileComplete,
|
||||||
|
staffName: staffName ?? this.staffName,
|
||||||
errorMessage: errorMessage ?? this.errorMessage,
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -51,6 +55,7 @@ class HomeState extends Equatable {
|
|||||||
recommendedShifts,
|
recommendedShifts,
|
||||||
autoMatchEnabled,
|
autoMatchEnabled,
|
||||||
isProfileComplete,
|
isProfileComplete,
|
||||||
|
staffName,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,12 @@ class WorkerHomePage extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const HomeHeader(),
|
BlocBuilder<HomeCubit, HomeState>(
|
||||||
|
buildWhen: (previous, current) => previous.staffName != current.staffName,
|
||||||
|
builder: (context, state) {
|
||||||
|
return HomeHeader(userName: state.staffName);
|
||||||
|
},
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: UiConstants.space4),
|
padding: const EdgeInsets.symmetric(horizontal: UiConstants.space4),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
@@ -2,15 +2,21 @@ import 'package:core_localization/core_localization.dart';
|
|||||||
import 'package:design_system/design_system.dart';
|
import 'package:design_system/design_system.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
/// Header widget for the staff home page, using design system tokens.
|
/// Header widget for the staff home page, using design system tokens.
|
||||||
class HomeHeader extends StatelessWidget {
|
class HomeHeader extends StatelessWidget {
|
||||||
|
final String? userName;
|
||||||
|
|
||||||
/// Creates a [HomeHeader].
|
/// Creates a [HomeHeader].
|
||||||
const HomeHeader({super.key});
|
const HomeHeader({super.key, this.userName});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final headerI18n = t.staff.home.header;
|
final headerI18n = t.staff.home.header;
|
||||||
|
final nameToDisplay = userName ?? headerI18n.user_name_placeholder;
|
||||||
|
final initial = nameToDisplay.isNotEmpty
|
||||||
|
? nameToDisplay[0].toUpperCase()
|
||||||
|
: 'K';
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.fromLTRB(
|
padding: EdgeInsets.fromLTRB(
|
||||||
UiConstants.space4,
|
UiConstants.space4,
|
||||||
@@ -18,7 +24,8 @@ class HomeHeader extends StatelessWidget {
|
|||||||
UiConstants.space4,
|
UiConstants.space4,
|
||||||
UiConstants.space3,
|
UiConstants.space3,
|
||||||
),
|
),
|
||||||
child:Row(
|
child: Row(
|
||||||
|
spacing: UiConstants.space3,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: 48,
|
width: 48,
|
||||||
@@ -32,27 +39,25 @@ class HomeHeader extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: UiColors.primary.withOpacity(0.1),
|
backgroundColor: UiColors.primary.withOpacity(0.1),
|
||||||
child: const Text(
|
child: Text(
|
||||||
'K',
|
initial,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
color: UiColors.primary,
|
color: UiColors.primary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: UiConstants.space3),
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
headerI18n.welcome_back,
|
headerI18n.welcome_back,
|
||||||
style: UiTypography.body3r.copyWith(color: UiColors.mutedForeground),
|
style: UiTypography.body3r.copyWith(
|
||||||
|
color: UiColors.mutedForeground,
|
||||||
),
|
),
|
||||||
Text(
|
|
||||||
headerI18n.user_name_placeholder,
|
|
||||||
style: UiTypography.headline4m,
|
|
||||||
),
|
),
|
||||||
|
Text(nameToDisplay, style: UiTypography.headline4m),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user