chnages has been made and net salary is being displayed

This commit is contained in:
Daniah Ayad Al-sultani
2026-02-11 14:31:03 +03:00
parent 1002937045
commit a7930d19e5
23 changed files with 691 additions and 141 deletions

View File

@@ -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)),
],
),
),
),

View File

@@ -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)),
),
),
);