feat(notifications): day sheet notification types
Add daySheetId field to NotificationItem model (Brick-managed), extract notificationTitle/notificationIcon to top-level testable functions, add five day-sheet notification cases, and wire tap/banner routing for day-sheet detail and approvals tab. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -16,6 +16,48 @@ import '../../widgets/responsive_body.dart';
|
||||
import '../../theme/app_surfaces.dart';
|
||||
import '../../theme/m3_motion.dart';
|
||||
|
||||
String notificationTitle(String type, String actorName) {
|
||||
return switch (type) {
|
||||
'assignment' => '$actorName assigned you',
|
||||
'created' => '$actorName created a new item',
|
||||
'swap_request' => '$actorName requested a shift swap',
|
||||
'swap_update' => '$actorName updated a swap request',
|
||||
'announcement' => '$actorName posted an announcement',
|
||||
'announcement_comment' => '$actorName commented on an announcement',
|
||||
'it_job_reminder' => 'IT Job submission reminder',
|
||||
'isr_approved' => 'IT Service Request approved',
|
||||
'isr_status_changed' => 'IT Service Request status updated',
|
||||
'isr_assigned' => '$actorName assigned you an IT Service Request',
|
||||
'day_sheet_submitted' => '$actorName submitted a day sheet',
|
||||
'day_sheet_disapproved' => 'Day sheet disapproved',
|
||||
'day_sheet_justified' => '$actorName justified a day sheet',
|
||||
'day_sheet_approved' => 'Day sheet approved',
|
||||
'day_sheet_digest' => 'Day sheets awaiting review',
|
||||
_ => '$actorName mentioned you',
|
||||
};
|
||||
}
|
||||
|
||||
IconData notificationIcon(String type) {
|
||||
return switch (type) {
|
||||
'assignment' => Icons.assignment_ind_outlined,
|
||||
'created' => Icons.campaign_outlined,
|
||||
'swap_request' => Icons.swap_horiz,
|
||||
'swap_update' => Icons.update,
|
||||
'announcement' => Icons.campaign,
|
||||
'announcement_comment' => Icons.comment_outlined,
|
||||
'it_job_reminder' => Icons.print,
|
||||
'isr_approved' => Icons.check_circle_outline,
|
||||
'isr_status_changed' => Icons.sync_alt_outlined,
|
||||
'isr_assigned' => Icons.engineering_outlined,
|
||||
'day_sheet_submitted' => Icons.assignment_turned_in_outlined,
|
||||
'day_sheet_disapproved' => Icons.report_outlined,
|
||||
'day_sheet_justified' => Icons.reply_outlined,
|
||||
'day_sheet_approved' => Icons.verified_outlined,
|
||||
'day_sheet_digest' => Icons.inbox_outlined,
|
||||
_ => Icons.alternate_email,
|
||||
};
|
||||
}
|
||||
|
||||
class NotificationsScreen extends ConsumerStatefulWidget {
|
||||
const NotificationsScreen({super.key});
|
||||
|
||||
@@ -80,42 +122,11 @@ class _NotificationsScreenState extends ConsumerState<NotificationsScreen> {
|
||||
};
|
||||
}
|
||||
|
||||
String _notificationTitle(String type, String actorName) {
|
||||
return switch (type) {
|
||||
'assignment' => '$actorName assigned you',
|
||||
'created' => '$actorName created a new item',
|
||||
'swap_request' => '$actorName requested a shift swap',
|
||||
'swap_update' => '$actorName updated a swap request',
|
||||
'announcement' => '$actorName posted an announcement',
|
||||
'announcement_comment' => '$actorName commented on an announcement',
|
||||
'it_job_reminder' => 'IT Job submission reminder',
|
||||
'isr_approved' => 'IT Service Request approved',
|
||||
'isr_status_changed' => 'IT Service Request status updated',
|
||||
'isr_assigned' => '$actorName assigned you an IT Service Request',
|
||||
_ => '$actorName mentioned you',
|
||||
};
|
||||
}
|
||||
|
||||
IconData _notificationIcon(String type) {
|
||||
return switch (type) {
|
||||
'assignment' => Icons.assignment_ind_outlined,
|
||||
'created' => Icons.campaign_outlined,
|
||||
'swap_request' => Icons.swap_horiz,
|
||||
'swap_update' => Icons.update,
|
||||
'announcement' => Icons.campaign,
|
||||
'announcement_comment' => Icons.comment_outlined,
|
||||
'it_job_reminder' => Icons.print,
|
||||
'isr_approved' => Icons.check_circle_outline,
|
||||
'isr_status_changed' => Icons.sync_alt_outlined,
|
||||
'isr_assigned' => Icons.engineering_outlined,
|
||||
_ => Icons.alternate_email,
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> _handleTap(BuildContext context, NotificationItem item) async {
|
||||
final ticketId = item.ticketId;
|
||||
final taskId = item.taskId;
|
||||
final isrId = item.itServiceRequestId;
|
||||
final daySheetId = item.daySheetId;
|
||||
|
||||
if (ticketId != null) {
|
||||
await ref
|
||||
@@ -136,6 +147,10 @@ class _NotificationsScreenState extends ConsumerState<NotificationsScreen> {
|
||||
context.go('/tickets/$ticketId');
|
||||
} else if (isrId != null) {
|
||||
context.go('/it-service-requests/$isrId');
|
||||
} else if (item.type == 'day_sheet_digest') {
|
||||
context.go('/programmer-tasks?tab=approvals');
|
||||
} else if (daySheetId != null) {
|
||||
context.go('/programmer-tasks/day-sheets/$daySheetId');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,8 +263,8 @@ class _NotificationsScreenState extends ConsumerState<NotificationsScreen> {
|
||||
animDelay: Duration(
|
||||
milliseconds: animIndexes[index].clamp(0, 6) * 50,
|
||||
),
|
||||
title: _notificationTitle(item.type, actorName),
|
||||
icon: _notificationIcon(item.type),
|
||||
title: notificationTitle(item.type, actorName),
|
||||
icon: notificationIcon(item.type),
|
||||
iconContainerColor:
|
||||
_iconContainerColor(context, item.type),
|
||||
iconForegroundColor:
|
||||
@@ -331,6 +346,7 @@ class _NotificationCard extends StatelessWidget {
|
||||
if (item.announcementId != null) return 'Announcement';
|
||||
if (item.taskId != null) return taskTitle ?? 'Task';
|
||||
if (item.itServiceRequestId != null) return 'IT Service Request';
|
||||
if (item.daySheetId != null) return 'Day Sheet';
|
||||
return ticketSubject ?? 'Ticket';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user