diff --git a/.gitignore b/.gitignore
index 3a83c2f0..1b90f0ec 100644
Binary files a/.gitignore and b/.gitignore differ
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..12ef85a0
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "cmake.sourceDirectory": "C:/Users/ludov/Desktop/UMGC stml/spring2025/STML/stml_application/linux"
+}
\ No newline at end of file
diff --git a/STML/stml_application/ios/Runner/Info.plist b/STML/stml_application/ios/Runner/Info.plist
index 1167b176..6275ef4e 100644
--- a/STML/stml_application/ios/Runner/Info.plist
+++ b/STML/stml_application/ios/Runner/Info.plist
@@ -58,6 +58,10 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ NSMicrophoneUsageDescription
+ We need microphone access to record audio for memory notes.
+ NSDocumentsFolderUsageDescription
+ This app needs access to save and read audio transcripts.
CADisableMinimumFrameDurationOnPhone
UIApplicationSupportsIndirectInputEvents
diff --git a/STML/stml_application/lib/services/notification_service.dart b/STML/stml_application/lib/services/notification_service.dart
new file mode 100644
index 00000000..ed055b7a
--- /dev/null
+++ b/STML/stml_application/lib/services/notification_service.dart
@@ -0,0 +1,250 @@
+//notification_service.dart
+import 'package:firebase_auth/firebase_auth.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+import 'package:cloud_functions/cloud_functions.dart';
+import 'package:geolocator/geolocator.dart';
+import 'package:geocoding/geocoding.dart';
+import 'package:memoryminder/ui/location_history_screen.dart';
+import 'package:firebase_analytics/firebase_analytics.dart';
+
+class NotificationService {
+ final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
+ final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
+ FlutterLocalNotificationsPlugin();
+ final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;
+
+ String? _caregiverToken;
+ String? _lastRequestId;
+
+ String? get lastRequestId => _lastRequestId;
+
+ Future initialize() async {
+ // Get the FCM token for the current device
+ _caregiverToken = await _firebaseMessaging.getToken();
+ print("Caregiver Token: $_caregiverToken");
+
+ // Log token generation for analytics
+ await _analytics.logEvent(
+ name: 'fcm_token_generated',
+ parameters: {
+ 'user_type': 'caregiver',
+ },
+ );
+
+ // Listen for new tokens (in case the token changes)
+ _firebaseMessaging.onTokenRefresh.listen((newToken) {
+ _caregiverToken = newToken;
+ print("New Caregiver Token: $_caregiverToken");
+
+ // Log token refresh for analytics
+ _analytics.logEvent(
+ name: 'fcm_token_refreshed',
+ parameters: {
+ 'user_type': 'caregiver',
+ },
+ );
+ });
+
+ // Configure local notifications
+ const AndroidInitializationSettings initializationSettingsAndroid =
+ AndroidInitializationSettings('@mipmap/ic_launcher');
+ final InitializationSettings initializationSettings =
+ InitializationSettings(
+ android: initializationSettingsAndroid,
+ );
+ await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
+
+ // Listen for incoming messages
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) {
+ print("Message received: ${message.notification?.title}");
+ _showNotification(message);
+
+ // Log message received for analytics
+ _analytics.logEvent(
+ name: 'notification_received',
+ parameters: {
+ 'notification_type': message.data['type'] ?? 'unknown',
+ 'has_notification': message.notification != null,
+ },
+ );
+ });
+ }
+
+ Future _showNotification(RemoteMessage message) async {
+ const AndroidNotificationDetails androidPlatformChannelSpecifics =
+ AndroidNotificationDetails(
+ 'your_channel_id', // Notification channel ID
+ 'your_channel_name', // Notification channel name
+ importance: Importance.max,
+ priority: Priority.high,
+ );
+ const NotificationDetails platformChannelSpecifics =
+ NotificationDetails(android: androidPlatformChannelSpecifics);
+
+ await _flutterLocalNotificationsPlugin.show(
+ 0, // Notification ID
+ message.notification?.title, // Notification title
+ message.notification?.body, // Notification body
+ platformChannelSpecifics,
+ );
+
+ // Log notification shown for analytics
+ await _analytics.logEvent(
+ name: 'notification_displayed',
+ parameters: {
+ 'notification_title': message.notification?.title ?? 'No title',
+ },
+ );
+ }
+
+ Future sendHelpNotification(LocationEntry? currentLocationEntry) async {
+ try {
+ // Start timer for performance tracking
+ final startTime = DateTime.now();
+
+ // Prepare location data
+ Map? locationData;
+
+ if (currentLocationEntry != null) {
+ try {
+ // Try to get the current coordinates
+ Position currentPosition = await Geolocator.getCurrentPosition();
+
+ // Create the data map with the stored address and current coordinates
+ locationData = {
+ 'address': currentLocationEntry.address,
+ 'latitude': currentPosition.latitude,
+ 'longitude': currentPosition.longitude,
+ 'timestamp': currentLocationEntry.startTime.toIso8601String()
+ };
+
+ // Log successful location capture
+ await _analytics.logEvent(
+ name: 'emergency_location_captured',
+ parameters: {
+ 'method': 'geolocator',
+ 'has_coordinates': true,
+ },
+ );
+ } catch (e) {
+ // Log location error
+ await _analytics.logEvent(
+ name: 'emergency_location_error',
+ parameters: {
+ 'error_type': 'geolocator_error',
+ 'error_message': e.toString(),
+ },
+ );
+
+ // Fallback: try to geocode the address to get coordinates
+ try {
+ List locations =
+ await locationFromAddress(currentLocationEntry.address);
+ if (locations.isNotEmpty) {
+ locationData = {
+ 'address': currentLocationEntry.address,
+ 'latitude': locations.first.latitude,
+ 'longitude': locations.first.longitude,
+ 'timestamp': currentLocationEntry.startTime.toIso8601String()
+ };
+
+ // Log successful geocoding
+ await _analytics.logEvent(
+ name: 'emergency_location_captured',
+ parameters: {
+ 'method': 'geocoding',
+ 'has_coordinates': true,
+ },
+ );
+ } else {
+ // If geocoding fails, only send the address
+ locationData = {
+ 'address': currentLocationEntry.address,
+ 'timestamp': currentLocationEntry.startTime.toIso8601String()
+ };
+
+ // Log geocoding with no results
+ await _analytics.logEvent(
+ name: 'emergency_location_captured',
+ parameters: {
+ 'method': 'geocoding',
+ 'has_coordinates': false,
+ },
+ );
+ }
+ } catch (e) {
+ // Log geocoding error
+ await _analytics.logEvent(
+ name: 'emergency_location_error',
+ parameters: {
+ 'error_type': 'geocoding_error',
+ 'error_message': e.toString(),
+ },
+ );
+
+ // As a last resort, only send the address
+ locationData = {
+ 'address': currentLocationEntry.address,
+ 'timestamp': currentLocationEntry.startTime.toIso8601String()
+ };
+ }
+ }
+ } else {
+ // Log no location available
+ await _analytics.logEvent(
+ name: 'emergency_location_missing',
+ );
+ }
+
+ // Call the Cloud Function
+ final HttpsCallable callable =
+ FirebaseFunctions.instance.httpsCallable('sendHelpAlert');
+ final result = await callable.call({
+ 'caregiverToken': _caregiverToken,
+ 'location': locationData,
+ 'userId': FirebaseAuth.instance.currentUser?.uid,
+ 'userName': FirebaseAuth.instance.currentUser?.displayName
+ });
+
+ // Save the request ID for later reference
+ _lastRequestId = result.data['requestId'];
+
+ // Calculate time taken
+ final endTime = DateTime.now();
+ final duration = endTime.difference(startTime).inMilliseconds;
+
+ // Create parameters map without nullable values
+ final Map analyticsParams = {
+ 'success': result.data['success'] ?? false,
+ 'has_location': currentLocationEntry != null,
+ 'processing_time_ms': duration,
+ };
+
+ // Add requestId only if it's not null
+ if (_lastRequestId != null) {
+ analyticsParams['request_id'] = _lastRequestId!;
+ }
+
+ // Log complete event with success/failure
+ await _analytics.logEvent(
+ name: 'emergency_alert_sent',
+ parameters: analyticsParams,
+ );
+
+ return result.data['success'] ?? false;
+ } catch (e) {
+ print("Error sending notification: $e");
+
+ // Log error event
+ await _analytics.logEvent(
+ name: 'emergency_alert_error',
+ parameters: {
+ 'error_message': e.toString(),
+ },
+ );
+
+ return false;
+ }
+ }
+}
diff --git a/STML/stml_application/lib/src/features/account_creation_and_login/presentation/login_screen.dart b/STML/stml_application/lib/src/features/account_creation_and_login/presentation/login_screen.dart
index 5d5ba93f..f704c7d5 100644
--- a/STML/stml_application/lib/src/features/account_creation_and_login/presentation/login_screen.dart
+++ b/STML/stml_application/lib/src/features/account_creation_and_login/presentation/login_screen.dart
@@ -6,6 +6,7 @@ Author: Eyerusalme (Jerry)
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:local_auth/local_auth.dart';
+import 'package:memoryminder/src/features/account_creation_and_login/presentation/eula_screen.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart';
import 'package:memoryminder/src/utils/permission_manager.dart';
import 'registration_screen.dart';
@@ -34,7 +35,7 @@ class _LoginScreenState extends State {
if (didAuthenticate) {
Navigator.pushReplacement(
context,
- MaterialPageRoute(builder: (context) => HomeScreen()),
+ MaterialPageRoute(builder: (context) => STMLUserDashboardScreen()),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
@@ -50,7 +51,6 @@ class _LoginScreenState extends State {
}
Future _loginWithEmail() async {
-
setState(() {
_isAuthenticating = true;
});
@@ -80,7 +80,6 @@ class _LoginScreenState extends State {
PermissionManager.checkIfLocationServiceIsActive(context);
return Scaffold(
body: Container(
-
child: Center(
child: Padding(
padding:
@@ -111,15 +110,14 @@ class _LoginScreenState extends State {
Image.asset('assets/welcome_image.png',
height: 300), // Add a nice image
TextFormField(
- controller: _emailController,
- decoration: InputDecoration(labelText: 'Email'),
- keyboardType: TextInputType.emailAddress,
- validator: (value) {
- if(value ==null || value.isEmpty) {
- return 'Please enter email';
- }
- }
- ),
+ controller: _emailController,
+ decoration: InputDecoration(labelText: 'Email'),
+ keyboardType: TextInputType.emailAddress,
+ validator: (value) {
+ if (value == null || value.isEmpty) {
+ return 'Please enter email';
+ }
+ }),
SizedBox(height: 10),
TextFormField(
controller: _passwordController,
@@ -145,10 +143,16 @@ class _LoginScreenState extends State {
? CircularProgressIndicator()
: ElevatedButton(
onPressed: _loginWithEmail,
- child: Text("Login", style: TextStyle(fontSize: 18, color: Colors.white),),
+ child: Text(
+ "Login",
+ style:
+ TextStyle(fontSize: 18, color: Colors.white),
+ ),
style: ElevatedButton.styleFrom(
- backgroundColor: const Color.fromARGB(255, 2, 63, 129),
- padding: EdgeInsets.symmetric(horizontal: 50, vertical: 15),
+ backgroundColor:
+ const Color.fromARGB(255, 2, 63, 129),
+ padding: EdgeInsets.symmetric(
+ horizontal: 50, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
@@ -160,11 +164,18 @@ class _LoginScreenState extends State {
ElevatedButton.icon(
onPressed: _authenticateWithBiometrics,
- icon: Icon(Icons.fingerprint, color: Colors.white,),
- label: Text("Login with Biometrics", style: TextStyle(fontSize: 18, color: Colors.white), ),
+ icon: Icon(
+ Icons.fingerprint,
+ color: Colors.white,
+ ),
+ label: Text(
+ "Login with Biometrics",
+ style: TextStyle(fontSize: 18, color: Colors.white),
+ ),
style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromARGB(255, 2, 63, 129),
- padding: EdgeInsets.symmetric(horizontal: 50, vertical: 15),
+ padding:
+ EdgeInsets.symmetric(horizontal: 50, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40),
),
@@ -176,7 +187,7 @@ class _LoginScreenState extends State {
Navigator.push(
context,
MaterialPageRoute(
- builder: (context) => RegistrationScreen()),
+ builder: (context) => EulaScreen()),
);
},
child: Row(
diff --git a/STML/stml_application/lib/src/features/account_creation_and_login/presentation/registration_screen.dart b/STML/stml_application/lib/src/features/account_creation_and_login/presentation/registration_screen.dart
index d2fa5003..6e3b4960 100644
--- a/STML/stml_application/lib/src/features/account_creation_and_login/presentation/registration_screen.dart
+++ b/STML/stml_application/lib/src/features/account_creation_and_login/presentation/registration_screen.dart
@@ -85,7 +85,6 @@ class _RegistrationScreenState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
- backgroundColor: const Color(0XFF880E4F),
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
@@ -97,12 +96,7 @@ class _RegistrationScreenState extends State {
const Text('Registration', style: TextStyle(color: Colors.black54)),
),
body: Container(
- decoration: const BoxDecoration(
- image: DecorationImage(
- image: AssetImage("assets/images/background.jpg"),
- fit: BoxFit.cover,
- ),
- ),
+
child: Center(
child: Padding(
padding:
diff --git a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/app_bar.dart b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/app_bar.dart
index e997970b..f96a2647 100644
--- a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/app_bar.dart
+++ b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/app_bar.dart
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
+import 'package:memoryminder/src/features/account_creation_and_login/presentation/login_screen.dart';
import 'package:memoryminder/ui/profile_screen.dart';
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
@@ -67,29 +68,20 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
// Widgets on the right side of the AppBar
actions: [
// First page icon to navigate back
- IconButton(
+
+
+// First page icon to navigate back
+ IconButton(
icon: const Icon(
- Icons.settings,
- color: Colors.white70,
+ Icons.logout,
+ color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
- MaterialPageRoute(builder: (context) => ProfileScreen()),
- );
- },
+ MaterialPageRoute(builder: (context) => LoginScreen()),
+ ); },
),
-
-// First page icon to navigate back
- /* IconButton(
- icon: const Icon(
- Icons.first_page,
- color: Colors.black87,
- ),
- onPressed: () {
- Navigator.pop(context);
- },
- ),*/
],
);
}
diff --git a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/care_recipient_profile.dart b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/care_recipient_profile.dart
index c9a4e730..c4038562 100644
--- a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/care_recipient_profile.dart
+++ b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/care_recipient_profile.dart
@@ -1,6 +1,7 @@
// ignore_for_file: avoid_print, prefer_const_constructors
// Imported libraries and packages
+import 'package:memoryminder/features/caregiver_task_management/caregiver_task_screen.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/presentation/add_care_recipient.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/presentation/app_bar.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart';
@@ -122,6 +123,22 @@ class CareRecipientProfileScreenState extends State
screen: DementiaResourcesScreen(loc: careRecipientLocation),
keyName: "DementiaResourcesButtonKey",
),
+ _buildElevatedButton(
+ context: context,
+ icon: Icon(Icons.task_alt,
+ size: iconSize, color: Color.fromARGB(255, 2, 63, 129)),
+ text: 'Tasks',
+ screen: CaregiverTaskScreen(),
+ keyName: "CaregiverTaskButtonKey",
+ ),
+ _buildElevatedButton(
+ context: context,
+ icon: Icon(Icons.language_outlined,
+ size: iconSize, color: Color.fromARGB(255, 2, 63, 129)),
+ text: 'Language Preferences',
+ keyName: "CaregiverTaskButtonKey",
+
+ ),
],
),
),
@@ -133,6 +150,10 @@ class CareRecipientProfileScreenState extends State
bottomNavigationBar: UiUtils.createBottomNavigationBar(context));
}
+ void _showLanguageDialog(BuildContext context) {
+
+}
+
// Helper function to create each button for the GridView
Widget _buildElevatedButton({
required BuildContext context,
@@ -141,6 +162,7 @@ class CareRecipientProfileScreenState extends State
Widget? screen,
String? routeName,
required String keyName,
+ VoidCallback? functionName,
}) {
return ElevatedButton(
key: Key(keyName),
diff --git a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart
index 26949d01..21426b0b 100644
--- a/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart
+++ b/STML/stml_application/lib/src/features/caregiver-dashboard/presentation/caregiver-dashboard.dart
@@ -10,10 +10,10 @@ import 'package:memoryminder/src/features/caregiver-dashboard/presentation/care_
import 'package:memoryminder/src/features/caregiver-dashboard/service/manage_care_recipient_service.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/service/notification_service.dart';
import 'package:memoryminder/src/features/caregiver-dashboard/service/notification_stream_service.dart';
-import 'package:memoryminder/ui/profile_screen.dart';
import 'package:memoryminder/src/utils/ui_utils.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
+import 'package:url_launcher/url_launcher.dart';
// Main HomeScreen widget which is a stateless widget.
class CaregiverDashboardScreen extends StatefulWidget {
@@ -33,6 +33,41 @@ class _CaregiverDashboardScreen extends State {
_careRecipientData = ManageCareRecipientService().getAllCareRecipients();
}
+ Future _callEmergencyNumber() async {
+ const String emergencyNumber = '911';
+ final Uri phoneUri = Uri(
+ scheme: 'tel',
+ path: emergencyNumber,
+ );
+
+ try {
+ if (await canLaunchUrl(phoneUri)) {
+ await launchUrl(
+ phoneUri,
+ mode: LaunchMode.externalApplication,
+ );
+ } else {
+ if (mounted) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Cannot launch dialer for $emergencyNumber'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ }
+ }
+ } catch (e) {
+ if (mounted) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Emergency call failed: ${e.toString()}'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ }
+ }
+ }
+
@override
void dispose() {
NotificationStreamService().dispose();
@@ -43,19 +78,10 @@ class _CaregiverDashboardScreen extends State {
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
- // Setting up the app bar at the top of the screen
appBar: const CustomAppBar(
title: 'Caregiver Dashboard',
),
-
body: Container(
- /*decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage('assets/images/background.jpg'),
- // Replace with your image path
- fit: BoxFit.cover,
- ),
- ),*/
child: Column(
children: [
const Padding(
@@ -105,14 +131,13 @@ class _CaregiverDashboardScreen extends State {
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
- borderRadius: BorderRadius.circular(10), // Rounded corners
+ borderRadius: BorderRadius.circular(10),
),
child: _buildNotificationList(
context: context,
),
),
),
-
const Divider(
color: Colors.black54,
thickness: 2,
@@ -120,7 +145,32 @@ class _CaregiverDashboardScreen extends State {
indent: 20,
endIndent: 20,
),
-
+ const Divider(
+ color: Colors.black54,
+ thickness: 2,
+ height: 10,
+ indent: 20,
+ endIndent: 20,
+ ),
+ ElevatedButton(
+ onPressed: _callEmergencyNumber,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.red,
+ padding:
+ const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
+ ),
+ child: const Text(
+ 'Emergency Call',
+ style: TextStyle(fontSize: 18, color: Colors.white),
+ ),
+ ),
+ const Divider(
+ color: Colors.black54,
+ thickness: 2,
+ height: 10,
+ indent: 20,
+ endIndent: 20,
+ ),
Padding(
padding: EdgeInsets.fromLTRB(2.0, 2, 2.0, 2),
child: Column(
@@ -138,7 +188,8 @@ class _CaregiverDashboardScreen extends State {
onPressed: () {
Navigator.push(
context,
- MaterialPageRoute(builder: (context) => AddCareRecipientForm()),
+ MaterialPageRoute(
+ builder: (context) => AddCareRecipientForm()),
);
},
icon: Icon(
@@ -149,18 +200,16 @@ class _CaregiverDashboardScreen extends State {
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.black,
- padding: EdgeInsets.fromLTRB(2.0, 2, 16.0, 2), // Apply padding here
+ padding: EdgeInsets.fromLTRB(2.0, 2, 16.0, 2),
),
),
],
),
),
-
-
Expanded(
- child: _buildCareRecipientsGrid(
- context: context,
- ),
+ child: _buildCareRecipientsGrid(
+ context: context,
+ ),
),
const Divider(
color: Colors.black,
@@ -172,8 +221,6 @@ class _CaregiverDashboardScreen extends State {
],
),
),
-
- // Bottom navigation bar with multiple options for quick navigation
bottomNavigationBar: UiUtils.createBottomNavigationBar(context));
}
@@ -187,61 +234,61 @@ class _CaregiverDashboardScreen extends State {
final data = snapshot.data!;
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 3, // Adjust as needed
- childAspectRatio: 1.30,
- mainAxisSpacing: 10,
- crossAxisSpacing: 10
- ),
+ crossAxisCount: 3,
+ childAspectRatio: 1.0,
+ mainAxisSpacing: 3,
+ crossAxisSpacing: 3),
itemCount: data.length,
itemBuilder: (context, index) {
final item = data[index];
- final String labelText = '${item['firstName'].toString()} ${item['lastName'].toString()}';
+ final String labelText =
+ '${item['firstName'].toString()} ${item['lastName'].toString()}';
final careRecipient = CareRecipient.fromMap(item);
- return InkWell( // Or InkWell for ripple effect
- onTap: () {
- // Handle item click
- print('Item ${item['firstName'].toString()} clicked');
- Navigator.push(
- context,
- MaterialPageRoute(builder: (context) => CareRecipientProfileScreen(careRecipientId: item['itemId'].toString(), careRecipientData: careRecipient.toMap())),
- );
- },
- borderRadius: BorderRadius.circular(12.0),
- child: Container(
- decoration: BoxDecoration(
- color: Colors.lightBlue[100],
- borderRadius: BorderRadius.circular(12.0),
- boxShadow: [
- BoxShadow(
- color: Colors.lightBlueAccent,
- spreadRadius: 1,
- blurRadius: 3,
- offset: const Offset(0, 2),
- ),
- ],
- ),
- padding: const EdgeInsets.all(16.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.person,
- size: 40.0,
- color: Color.fromARGB(255, 2, 63, 129),
- ),
- const SizedBox(height: 8.0),
- Text(
- labelText,
- textAlign: TextAlign.center,
- style: const TextStyle(
- fontWeight: FontWeight.w500,
- color: Colors.black87,
+ return InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => CareRecipientProfileScreen(
+ careRecipientId: item['itemId'].toString(),
+ careRecipientData: careRecipient.toMap())),
+ );
+ },
+ borderRadius: BorderRadius.circular(12.0),
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.lightGreen[100],
+ borderRadius: BorderRadius.circular(12.0),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.lightGreen.withOpacity(0.5),
+ spreadRadius: 1,
+ blurRadius: 3,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ padding: const EdgeInsets.all(3.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(
+ Icons.person,
+ size: 40.0,
+ color: Colors.green,
+ ),
+ const SizedBox(height: 8.0),
+ Text(
+ labelText,
+ textAlign: TextAlign.center,
+ style: const TextStyle(
+ fontWeight: FontWeight.w500,
+ color: Colors.black87,
),
),
],
),
- )
- );
+ ));
},
);
} else if (snapshot.hasError) {
@@ -270,7 +317,6 @@ class _CaregiverDashboardScreen extends State {
return Center(child: Text('No notifications available'));
}
- // List of notifications
List