feat: Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import 'package:auto_route/annotations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart' show Gap;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/features/notificatins/domain/notification_entity.dart';
|
||||
|
||||
import '../../../core/presentation/gen/assets.gen.dart';
|
||||
import '../../../core/presentation/styles/kw_text_styles.dart';
|
||||
import '../../../core/presentation/styles/theme.dart';
|
||||
import '../../../core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
|
||||
@RoutePage()
|
||||
class NotificationDetailsScreen extends StatelessWidget {
|
||||
final NotificationEntity notification;
|
||||
|
||||
const NotificationDetailsScreen({super.key, required this.notification});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(
|
||||
titleText: notification.type.name,
|
||||
),
|
||||
body: ScrollLayoutHelper(
|
||||
upperWidget: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Gap(16),
|
||||
_buildTitle(),
|
||||
Gap(24),
|
||||
Text(notification.title, style: AppTextStyles.headingH1),
|
||||
Gap(8),
|
||||
Text(notification.body,
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackBlack)),
|
||||
],
|
||||
),
|
||||
lowerWidget: _buildFooter(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFooter(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Gap(24),
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Best regards',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackBlack)),
|
||||
Gap(2),
|
||||
Text(
|
||||
'KROW Team',
|
||||
style: AppTextStyles.bodyMediumSmb,
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Assets.images.logo.svg(
|
||||
colorFilter: const ColorFilter.mode(
|
||||
AppColors.bgColorDark,
|
||||
BlendMode.srcIn,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Gap(24),
|
||||
KwButton.primary(
|
||||
label: 'Go to',
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Row _buildTitle() {
|
||||
return Row(
|
||||
children: [
|
||||
_buildIcon(),
|
||||
Gap(12),
|
||||
Text(notification.body, style: AppTextStyles.bodyMediumMed),
|
||||
Spacer(),
|
||||
Text(DateFormat('hh:mm a').format(notification.dateTime),
|
||||
style: AppTextStyles.bodyMediumMed)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container _buildIcon() {
|
||||
return Container(
|
||||
height: 36,
|
||||
width: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.bgColorDark,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Assets.images.icons.receiptSearch.svg(
|
||||
height: 16,
|
||||
width: 16,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
AppColors.primaryMint,
|
||||
BlendMode.srcIn,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../domain/bloc/notifications_bloc.dart';
|
||||
|
||||
@RoutePage()
|
||||
class NotificationFlowScreen extends StatelessWidget {
|
||||
const NotificationFlowScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AutoRouter();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import 'package:auto_route/annotations.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/features/notificatins/presentation/widgets/notification_list_item.dart';
|
||||
|
||||
import '../../../core/presentation/gen/assets.gen.dart';
|
||||
import '../../../core/presentation/styles/kw_text_styles.dart';
|
||||
import '../../../core/presentation/styles/theme.dart';
|
||||
import '../domain/bloc/notifications_bloc.dart';
|
||||
|
||||
@RoutePage()
|
||||
class NotificationsListScreen extends StatefulWidget {
|
||||
const NotificationsListScreen({super.key});
|
||||
|
||||
@override
|
||||
State<NotificationsListScreen> createState() =>
|
||||
_NotificationsListScreenState();
|
||||
}
|
||||
|
||||
class _NotificationsListScreenState extends State<NotificationsListScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<void> _refreshNotifications() async {
|
||||
context.read<NotificationsBloc>().add(NotificationsInitEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<NotificationsBloc, NotificationsState>(
|
||||
builder: (context, state) {
|
||||
final notifications = state.notifications;
|
||||
|
||||
final todayNotifications =
|
||||
notifications.where((n) => isToday(n.dateTime)).toList();
|
||||
final thisWeekNotifications =
|
||||
notifications.where((n) => isThisWeek(n.dateTime)).toList();
|
||||
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(
|
||||
centerTitle: false,
|
||||
titleText: 'Alerts',
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
onRefresh: _refreshNotifications,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: CustomScrollView(
|
||||
slivers:state.notifications.isEmpty?[
|
||||
SliverToBoxAdapter(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Gap(100),
|
||||
Assets.images.icons.calendar.svg(height: 36,width: 36, colorFilter: const ColorFilter.mode(AppColors.blackGray, BlendMode.srcIn)),
|
||||
Gap(16),
|
||||
Text(
|
||||
'No notifications yet',
|
||||
style: AppTextStyles.headingH3.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]: [
|
||||
SliverGap(24),
|
||||
if (todayNotifications.isNotEmpty)
|
||||
SliverToBoxAdapter(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
'Today',
|
||||
style: AppTextStyles.bodySmallMed,
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
final notification = todayNotifications[index];
|
||||
return NotificationListItem(notification: notification);
|
||||
},
|
||||
childCount: todayNotifications.length,
|
||||
),
|
||||
),
|
||||
if (thisWeekNotifications.isNotEmpty)
|
||||
SliverToBoxAdapter(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(bottom: 8),
|
||||
child: Text(
|
||||
'This week',
|
||||
style: AppTextStyles.bodySmallMed,
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
final notification = thisWeekNotifications[index];
|
||||
return NotificationListItem(notification: notification);
|
||||
},
|
||||
childCount: thisWeekNotifications.length,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
bool isToday(DateTime date) {
|
||||
final now = DateTime.now();
|
||||
return date.year == now.year &&
|
||||
date.month == now.month &&
|
||||
date.day == now.day;
|
||||
}
|
||||
|
||||
bool isThisWeek(DateTime date) {
|
||||
final now = DateTime.now();
|
||||
final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
|
||||
final endOfWeek = startOfWeek.add(Duration(days: 6));
|
||||
return date.isAfter(startOfWeek) &&
|
||||
date.isBefore(endOfWeek) &&
|
||||
!isToday(date);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart' show Gap;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:krow/core/application/routing/routes.gr.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_box_decorations.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/features/notificatins/domain/notification_entity.dart';
|
||||
|
||||
import '../../../../core/presentation/gen/assets.gen.dart';
|
||||
import '../../../../core/presentation/styles/theme.dart';
|
||||
|
||||
class NotificationListItem extends StatelessWidget {
|
||||
final NotificationEntity notification;
|
||||
|
||||
NotificationListItem({required this.notification})
|
||||
: super(key: Key(notification.id));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.router.push(NotificationDetailsRoute(notification: notification));
|
||||
},
|
||||
child: Container(
|
||||
decoration: KwBoxDecorations.white12,
|
||||
padding: const EdgeInsets.all(12),
|
||||
height: 72,
|
||||
child: Row(
|
||||
children: [
|
||||
_buildIcon(),
|
||||
Gap(12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(children: [
|
||||
Text(
|
||||
notification.title,
|
||||
style: AppTextStyles.bodyMediumMed,
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
DateFormat('hh:mm a').format(notification.dateTime),
|
||||
style: AppTextStyles.bodyMediumMed,
|
||||
),
|
||||
]),
|
||||
Gap(8),
|
||||
Text(
|
||||
notification.title,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: AppTextStyles.bodySmallMed,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildIcon() {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 48,
|
||||
width: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.bgColorDark,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Assets.images.icons.receiptSearch.svg(
|
||||
height: 24,
|
||||
width: 24,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
AppColors.primaryMint,
|
||||
BlendMode.srcIn,
|
||||
)),
|
||||
),
|
||||
),
|
||||
if (notification.isRead == false)
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: Container(
|
||||
height: 12,
|
||||
width: 12,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.statusError,
|
||||
border: Border.all(
|
||||
color: AppColors.grayWhite,
|
||||
width: 2,
|
||||
),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user