notifications page updates
parent
8b5c4d7575
commit
1edeff439e
@ -0,0 +1,284 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||||
|
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||||
|
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
|
class NotificationDetailsPage extends StatelessWidget {
|
||||||
|
final NotificationResponseModel notification;
|
||||||
|
|
||||||
|
const NotificationDetailsPage({
|
||||||
|
super.key,
|
||||||
|
required this.notification,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Debug logging
|
||||||
|
print('=== Notification Details ===');
|
||||||
|
print('Message: ${notification.message}');
|
||||||
|
print('MessageType: ${notification.messageType}');
|
||||||
|
print('MessageTypeData: ${notification.messageTypeData}');
|
||||||
|
print('VideoURL: ${notification.videoURL}');
|
||||||
|
print('========================');
|
||||||
|
|
||||||
|
return CollapsingListView(
|
||||||
|
title: "Notification Details".needTranslation,
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.share_outlined,
|
||||||
|
size: 24.h,
|
||||||
|
color: AppColors.textColor,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_shareNotification();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
// Notification content card
|
||||||
|
_buildNotificationCard(context),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
],
|
||||||
|
).paddingSymmetrical(24.w, 0.h),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNotificationCard(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||||
|
color: AppColors.whiteColor,
|
||||||
|
borderRadius: 24.h,
|
||||||
|
hasShadow: true,
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.all(16.h),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Date and Time row
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
// Time chip with clock icon
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.greyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.access_time, size: 12.w, color: AppColors.textColor),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
_formatTime(notification.isSentOn).toText10(
|
||||||
|
weight: FontWeight.w500,
|
||||||
|
color: AppColors.textColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.w),
|
||||||
|
// Date chip with calendar icon
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.greyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.calendar_today, size: 12.w, color: AppColors.textColor),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
_formatDate(notification.isSentOn).toText10(
|
||||||
|
weight: FontWeight.w500,
|
||||||
|
color: AppColors.textColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
|
||||||
|
// Notification message
|
||||||
|
if (notification.message != null && notification.message!.isNotEmpty)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
'Message'.needTranslation.toText14(
|
||||||
|
weight: FontWeight.w600,
|
||||||
|
color: AppColors.greyTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.h),
|
||||||
|
notification.message!.toText16(
|
||||||
|
weight: FontWeight.w400,
|
||||||
|
color: AppColors.textColor,
|
||||||
|
maxlines: 100,
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
// Notification image (if MessageType is "image")
|
||||||
|
if (notification.messageType != null &&
|
||||||
|
notification.messageType!.toLowerCase() == "image")
|
||||||
|
Builder(
|
||||||
|
builder: (context) {
|
||||||
|
// Try to get image URL from videoURL or messageTypeData
|
||||||
|
String? imageUrl;
|
||||||
|
|
||||||
|
if (notification.videoURL != null && notification.videoURL!.isNotEmpty) {
|
||||||
|
imageUrl = notification.videoURL;
|
||||||
|
print('Image URL from videoURL: $imageUrl');
|
||||||
|
} else if (notification.messageTypeData != null && notification.messageTypeData!.isNotEmpty) {
|
||||||
|
imageUrl = notification.messageTypeData;
|
||||||
|
print('Image URL from messageTypeData: $imageUrl');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageUrl == null || imageUrl.isEmpty) {
|
||||||
|
print('No image URL found. videoURL: ${notification.videoURL}, messageTypeData: ${notification.messageTypeData}');
|
||||||
|
return SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
'Attached Image'.needTranslation.toText14(
|
||||||
|
weight: FontWeight.w600,
|
||||||
|
color: AppColors.greyTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.h),
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(12.h),
|
||||||
|
child: Image.network(
|
||||||
|
imageUrl,
|
||||||
|
width: double.infinity,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
print('Error loading image: $error');
|
||||||
|
print('Image URL: $imageUrl');
|
||||||
|
return Container(
|
||||||
|
height: 200.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.greyColor.withValues(alpha: 0.2),
|
||||||
|
borderRadius: BorderRadius.circular(12.h),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.broken_image_outlined,
|
||||||
|
size: 48.h,
|
||||||
|
color: AppColors.greyTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.h),
|
||||||
|
'Failed to load image'.needTranslation.toText12(
|
||||||
|
color: AppColors.greyTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.h),
|
||||||
|
Text(
|
||||||
|
imageUrl!,
|
||||||
|
style: TextStyle(fontSize: 8, color: AppColors.greyTextColor),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
loadingBuilder: (context, child, loadingProgress) {
|
||||||
|
if (loadingProgress == null) {
|
||||||
|
print('Image loaded successfully');
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
height: 200.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.greyColor.withValues(alpha: 0.2),
|
||||||
|
borderRadius: BorderRadius.circular(12.h),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
value: loadingProgress.expectedTotalBytes != null
|
||||||
|
? loadingProgress.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
// Additional notification info
|
||||||
|
if (notification.notificationType != null && notification.notificationType!.isNotEmpty)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
'Type'.needTranslation.toText14(
|
||||||
|
weight: FontWeight.w600,
|
||||||
|
color: AppColors.greyTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.h),
|
||||||
|
notification.notificationType!.toText16(
|
||||||
|
weight: FontWeight.w400,
|
||||||
|
color: AppColors.textColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _shareNotification() async {
|
||||||
|
final String shareText = '''
|
||||||
|
${notification.message ?? 'Notification'}
|
||||||
|
|
||||||
|
Time: ${_formatTime(notification.isSentOn)}
|
||||||
|
Date: ${_formatDate(notification.isSentOn)}
|
||||||
|
${notification.notificationType != null ? '\nType: ${notification.notificationType}' : ''}
|
||||||
|
'''.trim();
|
||||||
|
|
||||||
|
await Share.share(shareText);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _formatTime(String? dateTimeString) {
|
||||||
|
if (dateTimeString == null || dateTimeString.isEmpty) return '--';
|
||||||
|
try {
|
||||||
|
final dateTime = DateUtil.convertStringToDate(dateTimeString);
|
||||||
|
return DateFormat('hh:mm a').format(dateTime);
|
||||||
|
} catch (e) {
|
||||||
|
return '--';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _formatDate(String? dateTimeString) {
|
||||||
|
if (dateTimeString == null || dateTimeString.isEmpty) return '--';
|
||||||
|
try {
|
||||||
|
final dateTime = DateUtil.convertStringToDate(dateTimeString);
|
||||||
|
return DateFormat('dd MMM yyyy').format(dateTime);
|
||||||
|
} catch (e) {
|
||||||
|
return '--';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue