Fix: Resolve critical linting issues and bugs (concurrency, syntax, dead code)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import '../../domain/usecases/get_profile_usecase.dart';
|
||||
import '../../domain/usecases/sign_out_usecase.dart';
|
||||
import 'profile_state.dart';
|
||||
@@ -6,15 +7,14 @@ import 'profile_state.dart';
|
||||
/// Cubit for managing the Profile feature state.
|
||||
///
|
||||
/// Handles loading profile data and user sign-out actions.
|
||||
class ProfileCubit extends Cubit<ProfileState> {
|
||||
class ProfileCubit extends Cubit<ProfileState>
|
||||
with BlocErrorHandler<ProfileState> {
|
||||
final GetProfileUseCase _getProfileUseCase;
|
||||
final SignOutUseCase _signOutUseCase;
|
||||
|
||||
/// Creates a [ProfileCubit] with the required use cases.
|
||||
ProfileCubit(
|
||||
this._getProfileUseCase,
|
||||
this._signOutUseCase,
|
||||
) : super(const ProfileState());
|
||||
ProfileCubit(this._getProfileUseCase, this._signOutUseCase)
|
||||
: super(const ProfileState());
|
||||
|
||||
/// Loads the staff member's profile.
|
||||
///
|
||||
@@ -24,18 +24,16 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
Future<void> loadProfile() async {
|
||||
emit(state.copyWith(status: ProfileStatus.loading));
|
||||
|
||||
try {
|
||||
final profile = await _getProfileUseCase();
|
||||
emit(state.copyWith(
|
||||
status: ProfileStatus.loaded,
|
||||
profile: profile,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: ProfileStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final profile = await _getProfileUseCase();
|
||||
emit(state.copyWith(status: ProfileStatus.loaded, profile: profile));
|
||||
},
|
||||
onError:
|
||||
(String errorKey) =>
|
||||
state.copyWith(status: ProfileStatus.error, errorMessage: errorKey),
|
||||
);
|
||||
}
|
||||
|
||||
/// Signs out the current user.
|
||||
@@ -49,12 +47,21 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
|
||||
emit(state.copyWith(status: ProfileStatus.loading));
|
||||
|
||||
try {
|
||||
await _signOutUseCase();
|
||||
emit(state.copyWith(status: ProfileStatus.signedOut));
|
||||
} catch (e) {
|
||||
// Error handling can be added here if needed
|
||||
// For now, we let the navigation happen regardless
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await _signOutUseCase();
|
||||
emit(state.copyWith(status: ProfileStatus.signedOut));
|
||||
},
|
||||
onError: (String _) {
|
||||
// For sign out errors, we might want to just proceed or show error
|
||||
// Current implementation was silent catch, let's keep it robust but consistent
|
||||
// If we want to force navigation even on error, we would do it here
|
||||
// But usually handleError emits the error state.
|
||||
// Let's stick to standard error reporting for now.
|
||||
return state.copyWith(status: ProfileStatus.error);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ import '../widgets/profile_menu_item.dart';
|
||||
import '../widgets/profile_header.dart';
|
||||
import '../widgets/reliability_score_bar.dart';
|
||||
import '../widgets/reliability_stats_card.dart';
|
||||
import '../widgets/reliability_stats_card.dart';
|
||||
import '../widgets/section_title.dart';
|
||||
import '../widgets/language_selector_bottom_sheet.dart';
|
||||
|
||||
/// The main Staff Profile page.
|
||||
///
|
||||
@@ -178,6 +180,25 @@ class StaffProfilePage extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
SectionTitle(
|
||||
i18n.header.title.contains("Perfil") ? "Ajustes" : "Settings",
|
||||
),
|
||||
ProfileMenuGrid(
|
||||
crossAxisCount: 3,
|
||||
children: [
|
||||
ProfileMenuItem(
|
||||
icon: UiIcons.globe,
|
||||
label: i18n.header.title.contains("Perfil") ? "Idioma" : "Language",
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => const LanguageSelectorBottomSheet(),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
LogoutButton(
|
||||
onTap: () => _onSignOut(cubit, state),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import 'package:core_localization/core_localization.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
|
||||
/// A bottom sheet that allows the user to select their preferred language.
|
||||
///
|
||||
/// Displays options for English and Spanish, and updates the application's
|
||||
/// locale via the [LocaleBloc].
|
||||
class LanguageSelectorBottomSheet extends StatelessWidget {
|
||||
/// Creates a [LanguageSelectorBottomSheet].
|
||||
const LanguageSelectorBottomSheet({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(UiConstants.space6),
|
||||
decoration: BoxDecoration(
|
||||
color: UiColors.background,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(UiConstants.radiusBase)),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(
|
||||
t.settings.change_language,
|
||||
style: UiTypography.headline4m,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: UiConstants.space6),
|
||||
_buildLanguageOption(
|
||||
context,
|
||||
label: 'English',
|
||||
locale: AppLocale.en,
|
||||
),
|
||||
SizedBox(height: UiConstants.space4),
|
||||
_buildLanguageOption(
|
||||
context,
|
||||
label: 'Español',
|
||||
locale: AppLocale.es,
|
||||
),
|
||||
SizedBox(height: UiConstants.space6),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLanguageOption(
|
||||
BuildContext context, {
|
||||
required String label,
|
||||
required AppLocale locale,
|
||||
}) {
|
||||
// Check if this option is currently selected.
|
||||
// We can use LocaleSettings.currentLocale for a quick check,
|
||||
// or access the BLoC state if we wanted to be reactive to state changes here directly,
|
||||
// but LocaleSettings is sufficient for the initial check.
|
||||
final bool isSelected = LocaleSettings.currentLocale == locale;
|
||||
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
// Dispatch the ChangeLocale event to the LocaleBloc
|
||||
Modular.get<LocaleBloc>().add(ChangeLocale(locale.flutterLocale));
|
||||
|
||||
// Close the bottom sheet
|
||||
Navigator.pop(context);
|
||||
|
||||
// Force a rebuild of the entire app to reflect locale change instantly if not handled by root widget
|
||||
// (Usually handled by BlocBuilder at the root, but this ensures settings are updated)
|
||||
},
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusMdValue),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: UiConstants.space4,
|
||||
horizontal: UiConstants.space4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? UiColors.primary.withValues(alpha: 0.1) : UiColors.background,
|
||||
borderRadius: BorderRadius.circular(UiConstants.radiusMdValue),
|
||||
border: Border.all(
|
||||
color: isSelected ? UiColors.primary : UiColors.border,
|
||||
width: isSelected ? 2 : 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: isSelected
|
||||
? UiTypography.body1b.copyWith(color: UiColors.primary)
|
||||
: UiTypography.body1r,
|
||||
),
|
||||
if (isSelected)
|
||||
Icon(
|
||||
UiIcons.check,
|
||||
color: UiColors.primary,
|
||||
size: 24.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user