feat: Centralized Error Handling & Crash Fixes
This commit is contained in:
@@ -42,8 +42,11 @@ class AttirePage extends StatelessWidget {
|
||||
body: BlocConsumer<AttireCubit, AttireState>(
|
||||
listener: (BuildContext context, AttireState state) {
|
||||
if (state.status == AttireStatus.failure) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(state.errorMessage ?? 'Error')),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: translateErrorKey(state.errorMessage ?? 'Error'),
|
||||
type: UiSnackbarType.error,
|
||||
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
|
||||
);
|
||||
}
|
||||
if (state.status == AttireStatus.saved) {
|
||||
|
||||
@@ -42,15 +42,13 @@ class EmergencyContactScreen extends StatelessWidget {
|
||||
|
||||
listener: (context, state) {
|
||||
if (state.status == EmergencyContactStatus.failure) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
type: UiSnackbarType.error,
|
||||
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -16,14 +16,11 @@ class EmergencyContactSaveButton extends StatelessWidget {
|
||||
listenWhen: (previous, current) => previous.status != current.status,
|
||||
listener: (context, state) {
|
||||
if (state.status == EmergencyContactStatus.saved) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'Emergency contacts saved successfully',
|
||||
style: UiTypography.body2r.textPrimary,
|
||||
),
|
||||
backgroundColor: UiColors.iconSuccess,
|
||||
),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: 'Emergency contacts saved successfully',
|
||||
type: UiSnackbarType.success,
|
||||
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -58,20 +58,21 @@ class ExperiencePage extends StatelessWidget {
|
||||
child: BlocConsumer<ExperienceBloc, ExperienceState>(
|
||||
listener: (context, state) {
|
||||
if (state.status == ExperienceStatus.success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Experience saved successfully')),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: 'Experience saved successfully',
|
||||
type: UiSnackbarType.success,
|
||||
margin: const EdgeInsets.only(bottom: 120, left: 16, right: 16),
|
||||
);
|
||||
Modular.to.pop();
|
||||
} else if (state.status == ExperienceStatus.failure) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
type: UiSnackbarType.error,
|
||||
margin: const EdgeInsets.only(bottom: 120, left: 16, right: 16),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'personal_info_state.dart';
|
||||
/// during onboarding or profile editing. It delegates business logic to
|
||||
/// use cases following Clean Architecture principles.
|
||||
class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
with BlocErrorHandler<PersonalInfoState>
|
||||
with BlocErrorHandler<PersonalInfoState>, SafeBloc<PersonalInfoEvent, PersonalInfoState>
|
||||
implements Disposable {
|
||||
/// Creates a [PersonalInfoBloc].
|
||||
///
|
||||
@@ -54,8 +54,8 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
'phone': staff.phone,
|
||||
'preferredLocations':
|
||||
staff.address != null
|
||||
? <String?>[staff.address]
|
||||
: <dynamic>[], // TODO: Map correctly when Staff entity supports list
|
||||
? <String>[staff.address!]
|
||||
: <String>[], // TODO: Map correctly when Staff entity supports list
|
||||
'avatar': staff.avatar,
|
||||
};
|
||||
|
||||
@@ -109,8 +109,8 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
'phone': updatedStaff.phone,
|
||||
'preferredLocations':
|
||||
updatedStaff.address != null
|
||||
? <String?>[updatedStaff.address]
|
||||
: <dynamic>[],
|
||||
? <String>[updatedStaff.address!]
|
||||
: <String>[],
|
||||
'avatar': updatedStaff.avatar,
|
||||
};
|
||||
|
||||
|
||||
@@ -28,24 +28,19 @@ class PersonalInfoPage extends StatelessWidget {
|
||||
child: BlocListener<PersonalInfoBloc, PersonalInfoState>(
|
||||
listener: (BuildContext context, PersonalInfoState state) {
|
||||
if (state.status == PersonalInfoStatus.saved) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(i18n.save_success),
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: i18n.save_success,
|
||||
type: UiSnackbarType.success,
|
||||
);
|
||||
Modular.to.pop();
|
||||
} else if (state.status == PersonalInfoStatus.error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
duration: const Duration(seconds: 3),
|
||||
),
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: state.errorMessage != null
|
||||
? translateErrorKey(state.errorMessage!)
|
||||
: 'An error occurred',
|
||||
type: UiSnackbarType.error,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user