loading indicater has been added

This commit is contained in:
Daniah Ayad Al-sultani
2026-02-17 17:19:53 +03:00
parent 5117fbdabe
commit 3a9e7ca8db
2 changed files with 260 additions and 237 deletions

View File

@@ -51,19 +51,24 @@ class _FinanceScreenState extends State<FinanceScreen> {
void _triggerLoad() {
if (_employeeId != null && _employeeId!.isNotEmpty) {
if (_financeBloc.state is FinanceInitial) {
_financeBloc.add(
LoadFinanceDataEvent(
employeeId: _employeeId!,
category: currentCategory,
month: selectedDate.month,
year: selectedDate.year,
),
);
}
_financeBloc.add(
LoadFinanceDataEvent(
employeeId: _employeeId!,
category: currentCategory,
month: selectedDate.month,
year: selectedDate.year,
),
);
}
}
Future<void> _onRefresh() async {
_triggerLoad();
await _financeBloc.stream.firstWhere(
(state) => state is FinanceLoaded || state is FinanceError,
);
}
@override
Widget build(BuildContext context) {
return BlocProvider.value(
@@ -71,145 +76,153 @@ class _FinanceScreenState extends State<FinanceScreen> {
child: Directionality(
textDirection: TextDirection.ltr,
child: SafeArea(
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(),
),
);
}
},
),
child: RefreshIndicator(
onRefresh: _onRefresh,
color: const Color(0xFF0A6B4A),
child: CustomScrollView(
controller: scrollController,
physics: const AlwaysScrollableScrollPhysics(
parent: BouncingScrollPhysics(),
),
const SliverToBoxAdapter(child: SizedBox(height: 5)),
/// 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),
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(),
),
);
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,
),
);
}
}
},
onCategoryChanged: (category) {
if (category != null) {
setState(() => currentCategory = category);
if (_employeeId != null && _employeeId!.isNotEmpty) {
_financeBloc.add(
LoadFinanceDataEvent(
employeeId: _employeeId!,
category: currentCategory,
month: selectedDate.month,
year: selectedDate.year,
),
);
}
}
},
);
},
} else if (index == 1) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const NotificationsScreen(),
),
);
}
},
),
),
),
const SliverToBoxAdapter(child: SizedBox(height: 5)),
/// 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) {
/// 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,
),
);
}
}
},
onCategoryChanged: (category) {
if (category != null) {
setState(() => currentCategory = category);
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: Text("لا توجد سجلات"),
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("لا توجد سجلات"),
),
),
);
}
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)),
],
),
),
),
),