feat: Add services for managing trip-related data

- Implement EmergencyService for handling emergency contacts per trip.
- Create GuestFlagService to manage guest mode flags for trips.
- Introduce NotificationService with local notification capabilities.
- Add OfflineFlagService for managing offline caching flags.
- Develop PackingService for shared packing lists per trip.
- Implement ReminderService for managing reminders/to-dos per trip.
- Create SosService for dispatching SOS events to a backend.
- Add StorageService with album image upload functionality.
- Implement TransportService for managing transport segments per trip.
- Create TripChecklistService for storing and retrieving trip checklists.
- Add TripDocumentService for persisting trip documents metadata.

test: Add unit tests for new services

- Implement tests for AlbumService, BudgetService, EmergencyService, GuestFlagService, PackingService, ReminderService, SosService, TransportService, TripChecklistService, and TripDocumentService.
- Ensure tests cover adding, loading, deleting, and handling corrupted payloads for each service.
This commit is contained in:
Van Leemput Dayron
2026-03-13 15:02:23 +01:00
parent 3215a990d1
commit 9b08b2896c
36 changed files with 4731 additions and 2 deletions

View File

@@ -6,6 +6,8 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:travel_mate/components/account/group_expenses_page.dart';
import 'package:travel_mate/components/activities/activities_page.dart';
import 'package:travel_mate/components/group/chat_group_content.dart';
@@ -50,6 +52,8 @@ class NotificationService {
if (_isInitialized) return;
await _requestPermissions();
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation('UTC'));
const androidSettings = AndroidInitializationSettings(
'@mipmap/ic_launcher',
@@ -411,4 +415,75 @@ class NotificationService {
payload: json.encode(message.data),
);
}
/// Shows a local push notification with a custom [title] and [body].
///
/// Used for recap/reminder notifications when on-device scheduling is desired.
Future<void> showLocalRecap({
required String title,
required String body,
}) async {
const androidDetails = AndroidNotificationDetails(
'recap_channel',
'Recap quotidien',
channelDescription: 'Notifications de récap voyage',
importance: Importance.max,
priority: Priority.high,
);
const iosDetails = DarwinNotificationDetails();
const details = NotificationDetails(
android: androidDetails,
iOS: iosDetails,
);
await _localNotifications.show(
DateTime.now().millisecondsSinceEpoch ~/ 1000,
title,
body,
details,
);
}
/// Schedules a local reminder notification at [dueAt] with [title]/[body].
Future<void> scheduleReminder({
required String id,
required String title,
required String body,
required DateTime dueAt,
}) async {
try {
final int notifId = id.hashCode & 0x7fffffff;
final scheduled = tz.TZDateTime.from(dueAt, tz.local);
const androidDetails = AndroidNotificationDetails(
'reminder_channel',
'Rappels voyage',
channelDescription: 'Notifications des rappels/to-dos',
importance: Importance.high,
priority: Priority.high,
);
const iosDetails = DarwinNotificationDetails();
const details = NotificationDetails(
android: androidDetails,
iOS: iosDetails,
);
await _localNotifications.zonedSchedule(
notifId,
title,
body,
scheduled,
details,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
);
} catch (e) {
LoggerService.error('Failed to schedule reminder', error: e);
}
}
/// Cancels a scheduled reminder notification by [id].
Future<void> cancelReminder(String id) async {
final notifId = id.hashCode & 0x7fffffff;
await _localNotifications.cancel(notifId);
}
}