chnages has been made and net salary is being displayed
This commit is contained in:
@@ -3,6 +3,7 @@ import '../../../domain/usecases/get_attendance_records_usecase.dart';
|
||||
import '../../../domain/usecases/get_extra_hours_usecase.dart';
|
||||
import '../../../domain/usecases/get_rewards_usecase.dart';
|
||||
import '../../../domain/usecases/get_punishments_usecase.dart';
|
||||
import '../../../domain/usecases/get_salary_summary_usecase.dart';
|
||||
import '../../../domain/models/finance_record.dart';
|
||||
import '../../../domain/models/finance_category.dart';
|
||||
import '../../../core/error/exceptions.dart';
|
||||
@@ -13,8 +14,15 @@ abstract class FinanceEvent {}
|
||||
class LoadFinanceDataEvent extends FinanceEvent {
|
||||
final String employeeId;
|
||||
final FinanceCategory category;
|
||||
final int? month;
|
||||
final int? year;
|
||||
|
||||
LoadFinanceDataEvent({required this.employeeId, required this.category});
|
||||
LoadFinanceDataEvent({
|
||||
required this.employeeId,
|
||||
required this.category,
|
||||
this.month,
|
||||
this.year,
|
||||
});
|
||||
}
|
||||
|
||||
// States
|
||||
@@ -27,8 +35,13 @@ class FinanceLoading extends FinanceState {}
|
||||
class FinanceLoaded extends FinanceState {
|
||||
final List<FinanceRecord> records;
|
||||
final FinanceCategory category;
|
||||
final double netSalary;
|
||||
|
||||
FinanceLoaded({required this.records, required this.category});
|
||||
FinanceLoaded({
|
||||
required this.records,
|
||||
required this.category,
|
||||
this.netSalary = 0.0,
|
||||
});
|
||||
}
|
||||
|
||||
class FinanceError extends FinanceState {
|
||||
@@ -43,12 +56,14 @@ class FinanceBloc extends Bloc<FinanceEvent, FinanceState> {
|
||||
final GetExtraHoursUseCase getExtraHoursUseCase;
|
||||
final GetRewardsUseCase getRewardsUseCase;
|
||||
final GetPunishmentsUseCase getPunishmentsUseCase;
|
||||
final GetSalarySummaryUseCase getSalarySummaryUseCase;
|
||||
|
||||
FinanceBloc({
|
||||
required this.getAttendanceRecordsUseCase,
|
||||
required this.getExtraHoursUseCase,
|
||||
required this.getRewardsUseCase,
|
||||
required this.getPunishmentsUseCase,
|
||||
required this.getSalarySummaryUseCase,
|
||||
}) : super(FinanceInitial()) {
|
||||
on<LoadFinanceDataEvent>(_onLoadFinanceData);
|
||||
}
|
||||
@@ -64,6 +79,27 @@ class FinanceBloc extends Bloc<FinanceEvent, FinanceState> {
|
||||
|
||||
emit(FinanceLoading());
|
||||
try {
|
||||
final now = DateTime.now();
|
||||
final month = event.month ?? now.month;
|
||||
final year = event.year ?? now.year;
|
||||
double netSalary = 0.0;
|
||||
|
||||
print(
|
||||
'Fetching salary for Employee: ${event.employeeId}, Month: $month, Year: $year',
|
||||
);
|
||||
try {
|
||||
final salaryModel = await getSalarySummaryUseCase.execute(
|
||||
employeeId: event.employeeId,
|
||||
month: month,
|
||||
year: year,
|
||||
);
|
||||
print('Salary Model fetched: ${salaryModel.netAmount}');
|
||||
netSalary = salaryModel.netAmount;
|
||||
} catch (e) {
|
||||
print('Error fetching salary: $e');
|
||||
// We continue even if salary fails, to show the list at least
|
||||
}
|
||||
|
||||
List<FinanceRecord> records;
|
||||
switch (event.category) {
|
||||
case FinanceCategory.attendance:
|
||||
@@ -87,7 +123,13 @@ class FinanceBloc extends Bloc<FinanceEvent, FinanceState> {
|
||||
);
|
||||
break;
|
||||
}
|
||||
emit(FinanceLoaded(records: records, category: event.category));
|
||||
emit(
|
||||
FinanceLoaded(
|
||||
records: records,
|
||||
category: event.category,
|
||||
netSalary: netSalary,
|
||||
),
|
||||
);
|
||||
} on ServerException catch (e) {
|
||||
emit(FinanceError(message: e.message));
|
||||
} on NetworkException catch (e) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../domain/usecases/change_password_usecase.dart';
|
||||
import 'change_password_event.dart';
|
||||
import 'change_password_state.dart';
|
||||
|
||||
class ChangePasswordBloc
|
||||
extends Bloc<ChangePasswordEvent, ChangePasswordState> {
|
||||
final ChangePasswordUseCase changePasswordUseCase;
|
||||
|
||||
ChangePasswordBloc({required this.changePasswordUseCase})
|
||||
: super(const ChangePasswordInitial()) {
|
||||
on<ChangePasswordSubmitted>(_onChangePasswordSubmitted);
|
||||
on<ChangePasswordReset>(_onChangePasswordReset);
|
||||
}
|
||||
|
||||
Future<void> _onChangePasswordSubmitted(
|
||||
ChangePasswordSubmitted event,
|
||||
Emitter<ChangePasswordState> emit,
|
||||
) async {
|
||||
emit(const ChangePasswordLoading());
|
||||
|
||||
final result = await changePasswordUseCase(event.request);
|
||||
|
||||
result.fold((failure) => emit(ChangePasswordError(failure.message)), (
|
||||
response,
|
||||
) {
|
||||
if (response.isSuccess) {
|
||||
emit(ChangePasswordSuccess(response.message));
|
||||
} else {
|
||||
emit(ChangePasswordError(response.message));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _onChangePasswordReset(
|
||||
ChangePasswordReset event,
|
||||
Emitter<ChangePasswordState> emit,
|
||||
) {
|
||||
emit(const ChangePasswordInitial());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import '../../../domain/models/change_password_request.dart';
|
||||
|
||||
abstract class ChangePasswordEvent {}
|
||||
|
||||
class ChangePasswordSubmitted extends ChangePasswordEvent {
|
||||
final ChangePasswordRequest request;
|
||||
|
||||
ChangePasswordSubmitted(this.request);
|
||||
}
|
||||
|
||||
class ChangePasswordReset extends ChangePasswordEvent {}
|
||||
@@ -0,0 +1,23 @@
|
||||
abstract class ChangePasswordState {
|
||||
const ChangePasswordState();
|
||||
}
|
||||
|
||||
class ChangePasswordInitial extends ChangePasswordState {
|
||||
const ChangePasswordInitial();
|
||||
}
|
||||
|
||||
class ChangePasswordLoading extends ChangePasswordState {
|
||||
const ChangePasswordLoading();
|
||||
}
|
||||
|
||||
class ChangePasswordSuccess extends ChangePasswordState {
|
||||
final String message;
|
||||
|
||||
const ChangePasswordSuccess(this.message);
|
||||
}
|
||||
|
||||
class ChangePasswordError extends ChangePasswordState {
|
||||
final String message;
|
||||
|
||||
const ChangePasswordError(this.message);
|
||||
}
|
||||
@@ -22,18 +22,22 @@ class FinanceScreen extends StatefulWidget {
|
||||
class _FinanceScreenState extends State<FinanceScreen> {
|
||||
FinanceCategory currentCategory = FinanceCategory.attendance;
|
||||
late ScrollController scrollController;
|
||||
late FinanceBloc _financeBloc;
|
||||
String? _employeeId;
|
||||
DateTime selectedDate = DateTime.now();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
scrollController = ScrollController();
|
||||
_financeBloc = sl<FinanceBloc>();
|
||||
_loadInitialData();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
_financeBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -41,17 +45,19 @@ class _FinanceScreenState extends State<FinanceScreen> {
|
||||
_employeeId = await sl<UserLocalDataSource>().getCachedEmployeeId();
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
_triggerLoad();
|
||||
}
|
||||
}
|
||||
|
||||
void _triggerLoad(BuildContext context) {
|
||||
void _triggerLoad() {
|
||||
if (_employeeId != null && _employeeId!.isNotEmpty) {
|
||||
final bloc = context.read<FinanceBloc>();
|
||||
if (bloc.state is FinanceInitial) {
|
||||
bloc.add(
|
||||
if (_financeBloc.state is FinanceInitial) {
|
||||
_financeBloc.add(
|
||||
LoadFinanceDataEvent(
|
||||
employeeId: _employeeId!,
|
||||
category: currentCategory,
|
||||
month: selectedDate.month,
|
||||
year: selectedDate.year,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -60,128 +66,150 @@ class _FinanceScreenState extends State<FinanceScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<FinanceBloc>(),
|
||||
return BlocProvider.value(
|
||||
value: _financeBloc,
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: SafeArea(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
// Trigger initial load when bloc is ready
|
||||
_triggerLoad(context);
|
||||
child: CustomScrollView(
|
||||
controller: scrollController,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: SettingsBar(
|
||||
selectedIndex: 0,
|
||||
showBackButton: false,
|
||||
iconPaths: const [
|
||||
'assets/images/user.svg',
|
||||
'assets/images/ball.svg',
|
||||
],
|
||||
onTap: (index) {
|
||||
if (index == 0) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const UserSettingsScreen(),
|
||||
),
|
||||
);
|
||||
} else if (index == 1) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const NotificationsScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 5)),
|
||||
|
||||
return CustomScrollView(
|
||||
controller: scrollController,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: SettingsBar(
|
||||
selectedIndex: 0,
|
||||
showBackButton: false,
|
||||
iconPaths: const [
|
||||
'assets/images/user.svg',
|
||||
'assets/images/ball.svg',
|
||||
],
|
||||
onTap: (index) {
|
||||
if (index == 0) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const UserSettingsScreen(),
|
||||
),
|
||||
);
|
||||
} else if (index == 1) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const NotificationsScreen(),
|
||||
),
|
||||
);
|
||||
/// SUMMARY CARD
|
||||
SliverToBoxAdapter(
|
||||
child: BlocBuilder<FinanceBloc, FinanceState>(
|
||||
buildWhen: (previous, current) => current is FinanceLoaded,
|
||||
builder: (context, state) {
|
||||
String amount = "0";
|
||||
if (state is FinanceLoaded) {
|
||||
amount = state.netSalary.toStringAsFixed(0);
|
||||
amount = amount.replaceAllMapped(
|
||||
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
|
||||
(Match m) => '${m[1]},',
|
||||
);
|
||||
}
|
||||
|
||||
return FinanceSummaryCard(
|
||||
totalAmount: amount,
|
||||
currentCategory: currentCategory,
|
||||
onCalendarTap: () async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: selectedDate,
|
||||
firstDate: DateTime(2020),
|
||||
lastDate: DateTime(2030),
|
||||
);
|
||||
if (date != null && mounted) {
|
||||
setState(() => selectedDate = date);
|
||||
if (_employeeId != null && _employeeId!.isNotEmpty) {
|
||||
_financeBloc.add(
|
||||
LoadFinanceDataEvent(
|
||||
employeeId: _employeeId!,
|
||||
category: currentCategory,
|
||||
month: selectedDate.month,
|
||||
year: selectedDate.year,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 5)),
|
||||
|
||||
/// SUMMARY CARD
|
||||
SliverToBoxAdapter(
|
||||
child: FinanceSummaryCard(
|
||||
totalAmount: "333,000",
|
||||
currentCategory: currentCategory,
|
||||
onCalendarTap:
|
||||
() => showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2020),
|
||||
lastDate: DateTime(2030),
|
||||
),
|
||||
onCategoryChanged: (category) {
|
||||
if (category != null) {
|
||||
setState(() => currentCategory = category);
|
||||
context.read<FinanceBloc>().add(
|
||||
LoadFinanceDataEvent(
|
||||
employeeId: _employeeId ?? '',
|
||||
category: currentCategory,
|
||||
),
|
||||
);
|
||||
if (_employeeId != null && _employeeId!.isNotEmpty) {
|
||||
_financeBloc.add(
|
||||
LoadFinanceDataEvent(
|
||||
employeeId: _employeeId!,
|
||||
category: currentCategory,
|
||||
month: selectedDate.month,
|
||||
year: selectedDate.year,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
/// DATA LIST
|
||||
BlocBuilder<FinanceBloc, FinanceState>(
|
||||
builder: (context, state) {
|
||||
if (state is FinanceLoading || state is FinanceInitial) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
/// DATA LIST
|
||||
BlocBuilder<FinanceBloc, FinanceState>(
|
||||
builder: (context, state) {
|
||||
if (state is FinanceLoading || state is FinanceInitial) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state is FinanceLoaded) {
|
||||
if (state.records.isEmpty) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Text("لا توجد سجلات"),
|
||||
),
|
||||
);
|
||||
} else if (state is FinanceLoaded) {
|
||||
if (state.records.isEmpty) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Text("لا توجد سجلات"),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SliverList(
|
||||
delegate: SliverChildBuilderDelegate((
|
||||
context,
|
||||
index,
|
||||
) {
|
||||
return WorkDayCard(record: state.records[index]);
|
||||
}, childCount: state.records.length),
|
||||
);
|
||||
} else if (state is FinanceError) {
|
||||
return SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Text(
|
||||
state.message,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SliverList(
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return WorkDayCard(record: state.records[index]);
|
||||
}, childCount: state.records.length),
|
||||
);
|
||||
} else if (state is FinanceError) {
|
||||
return SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Text(
|
||||
state.message,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SliverToBoxAdapter(child: SizedBox());
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SliverToBoxAdapter(child: SizedBox());
|
||||
},
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 120)),
|
||||
],
|
||||
);
|
||||
},
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 120)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -13,11 +13,11 @@ import '../../core/services/request_service.dart';
|
||||
import '../../core/di/injection_container.dart';
|
||||
import '../../domain/usecases/get_vacations_usecase.dart';
|
||||
import '../../domain/usecases/get_advances_usecase.dart';
|
||||
import '../../domain/models/vacations_list_response_model.dart';
|
||||
// import '../../domain/models/vacations_list_response_model.dart';
|
||||
import '../../domain/models/vacation_response_model.dart';
|
||||
import '../../domain/models/advances_list_response_model.dart';
|
||||
// import '../../domain/models/advances_list_response_model.dart';
|
||||
import '../../domain/models/advance_request_model.dart';
|
||||
import '../../core/error/failures.dart';
|
||||
// import '../../core/error/failures.dart';
|
||||
|
||||
class HolidayScreen extends StatefulWidget {
|
||||
final void Function(bool isScrollingDown)? onScrollEvent;
|
||||
@@ -118,9 +118,10 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
(response) {
|
||||
if (mounted && response.data != null) {
|
||||
setState(() {
|
||||
_leaveRequests = response.data!.items
|
||||
.map((vacation) => _convertVacationToLeaveRequest(vacation))
|
||||
.toList();
|
||||
_leaveRequests =
|
||||
response.data!.items
|
||||
.map((vacation) => _convertVacationToLeaveRequest(vacation))
|
||||
.toList();
|
||||
_isLoadingVacations = false;
|
||||
});
|
||||
}
|
||||
@@ -141,7 +142,8 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
String leaveTypeName = _getArabicVacationTypeName(vacation.type);
|
||||
|
||||
// Check if it's timed leave (same day but different times)
|
||||
bool isTimedLeave = vacation.startDate.year == vacation.endDate.year &&
|
||||
bool isTimedLeave =
|
||||
vacation.startDate.year == vacation.endDate.year &&
|
||||
vacation.startDate.month == vacation.endDate.month &&
|
||||
vacation.startDate.day == vacation.endDate.day &&
|
||||
vacation.startDate.hour != vacation.endDate.hour;
|
||||
@@ -200,9 +202,10 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
(response) {
|
||||
if (mounted && response.data != null) {
|
||||
setState(() {
|
||||
_advanceRequests = response.data!.items
|
||||
.map((advance) => _convertAdvanceToAdvanceRequest(advance))
|
||||
.toList();
|
||||
_advanceRequests =
|
||||
response.data!.items
|
||||
.map((advance) => _convertAdvanceToAdvanceRequest(advance))
|
||||
.toList();
|
||||
_isLoadingAdvances = false;
|
||||
});
|
||||
}
|
||||
@@ -417,9 +420,7 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(40.0),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xFF8EFDC2),
|
||||
),
|
||||
child: CircularProgressIndicator(color: Color(0xFF8EFDC2)),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -458,9 +459,7 @@ class _HolidayScreenState extends State<HolidayScreen> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(40.0),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Color(0xFF8EFDC2),
|
||||
),
|
||||
child: CircularProgressIndicator(color: Color(0xFF8EFDC2)),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../core/di/injection_container.dart';
|
||||
import '../../domain/models/change_password_request.dart';
|
||||
import '../blocs/change_password/change_password_bloc.dart';
|
||||
import '../blocs/change_password/change_password_event.dart';
|
||||
import '../blocs/change_password/change_password_state.dart';
|
||||
import 'onboarding_button.dart';
|
||||
|
||||
class ChangePasswordModal extends StatefulWidget {
|
||||
@@ -10,7 +16,17 @@ class ChangePasswordModal extends StatefulWidget {
|
||||
|
||||
class _ChangePasswordModalState extends State<ChangePasswordModal> {
|
||||
bool _oldObscure = true;
|
||||
// bool _newObscure = true;
|
||||
bool _newObscure = true;
|
||||
|
||||
final TextEditingController _oldPasswordController = TextEditingController();
|
||||
final TextEditingController _newPasswordController = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_oldPasswordController.dispose();
|
||||
_newPasswordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -73,10 +89,11 @@ class _ChangePasswordModalState extends State<ChangePasswordModal> {
|
||||
const SizedBox(height: 8),
|
||||
|
||||
_buildField(
|
||||
controller: _oldPasswordController,
|
||||
hint: "أدخل كلمة المرور",
|
||||
obscure: _oldObscure,
|
||||
fontSize: fieldFontSize,
|
||||
hasEye: true, // ✅ eye here
|
||||
hasEye: true,
|
||||
onEyeTap:
|
||||
() => setState(() => _oldObscure = !_oldObscure),
|
||||
),
|
||||
@@ -98,21 +115,75 @@ class _ChangePasswordModalState extends State<ChangePasswordModal> {
|
||||
const SizedBox(height: 8),
|
||||
|
||||
_buildField(
|
||||
controller: _newPasswordController,
|
||||
hint: "كلمة المرور",
|
||||
obscure: false,
|
||||
obscure: _newObscure,
|
||||
fontSize: fieldFontSize,
|
||||
hasEye: false,
|
||||
onEyeTap: () {}, // unused
|
||||
hasEye: true,
|
||||
onEyeTap:
|
||||
() => setState(() => _newObscure = !_newObscure),
|
||||
),
|
||||
|
||||
SizedBox(height: buttonSpacing),
|
||||
|
||||
Center(
|
||||
child: OnboardingButton(
|
||||
text: "حفظ التغيير",
|
||||
backgroundColor: const Color(0xEE23574A),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
BlocProvider(
|
||||
create: (context) => sl<ChangePasswordBloc>(),
|
||||
child: BlocConsumer<
|
||||
ChangePasswordBloc,
|
||||
ChangePasswordState
|
||||
>(
|
||||
listener: (context, state) {
|
||||
if (state is ChangePasswordSuccess) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.message),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
} else if (state is ChangePasswordError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.message),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is ChangePasswordLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return Center(
|
||||
child: OnboardingButton(
|
||||
text: "حفظ التغيير",
|
||||
backgroundColor: const Color(0xEE23574A),
|
||||
onPressed: () {
|
||||
if (_oldPasswordController.text.isEmpty ||
|
||||
_newPasswordController.text.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("يرجى ملء جميع الحقول"),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
context.read<ChangePasswordBloc>().add(
|
||||
ChangePasswordSubmitted(
|
||||
ChangePasswordRequest(
|
||||
oldPassword: _oldPasswordController.text,
|
||||
newPassword: _newPasswordController.text,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -127,6 +198,7 @@ class _ChangePasswordModalState extends State<ChangePasswordModal> {
|
||||
}
|
||||
|
||||
Widget _buildField({
|
||||
required TextEditingController controller,
|
||||
required String hint,
|
||||
required bool obscure,
|
||||
required double fontSize,
|
||||
@@ -142,6 +214,7 @@ class _ChangePasswordModalState extends State<ChangePasswordModal> {
|
||||
],
|
||||
),
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
obscureText: obscure,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(fontSize: fontSize),
|
||||
|
||||
Reference in New Issue
Block a user