Add launch configuration, update API keys, and refactor UI components for better structure and performance
This commit is contained in:
31
.vscode/launch.json
vendored
Normal file
31
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Flutter",
|
||||||
|
"type": "dart",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "lib/main.dart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "travel_mate",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "travel_mate (profile mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "profile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "travel_mate (release mode)",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
android:value="2" />
|
android:value="2" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.google.android.geo.API_KEY"
|
android:name="com.google.android.geo.API_KEY"
|
||||||
android:value="AIzaSyAAQd5UqtPc0fsbHnuezm22r9b5dgzv21Y"/>
|
android:value="AIzaSyCAtz1_d5K0ANwxAA_T84iq7Ac_gsUs_oM"/>
|
||||||
</application>
|
</application>
|
||||||
<!-- Required to query activities that can process text, see:
|
<!-- Required to query activities that can process text, see:
|
||||||
https://developer.android.com/training/package-visibility and
|
https://developer.android.com/training/package-visibility and
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import GoogleMaps
|
|||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
GMSServices.provideAPIKey("AIzaSyDoflpihvRWaQx18SKMu8_fgirF0muW4yU")
|
GMSServices.provideAPIKey("AIzaSyBsgaG8PuDTFodn4xjGSjVDOxzw3gJB35A")
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,23 @@ class CountContent extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Center(
|
||||||
appBar: AppBar(title: const Text('Count Page')),
|
child: Column(
|
||||||
body: const Center(child: Text('This is the Count Page')),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.account_balance_wallet, size: 64, color: Colors.green),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Comptes et Budget',
|
||||||
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Gérez vos dépenses de voyage',
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,23 @@ class GroupContent extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Center(
|
||||||
appBar: AppBar(title: const Text('Chat Group Page')),
|
child: Column(
|
||||||
body: const Center(child: Text('This is the Chat Group Page')),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.group, size: 64, color: Colors.blue),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Chat de Groupe',
|
||||||
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Communiquez avec vos compagnons de voyage',
|
||||||
|
style: TextStyle(fontSize: 16, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import '../../providers/user_provider.dart';
|
|
||||||
|
|
||||||
class CreateTripContent extends StatefulWidget {
|
class CreateTripContent extends StatefulWidget {
|
||||||
const CreateTripContent({super.key});
|
const CreateTripContent({super.key});
|
||||||
@@ -350,11 +349,13 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
|
|
||||||
Future<void> _selectEndDate(BuildContext context) async {
|
Future<void> _selectEndDate(BuildContext context) async {
|
||||||
if (_startDate == null) {
|
if (_startDate == null) {
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Veuillez d\'abord sélectionner la date de début'),
|
content: Text('Veuillez d\'abord sélectionner la date de début'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +365,7 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
firstDate: _startDate!,
|
firstDate: _startDate!,
|
||||||
lastDate: DateTime.now().add(Duration(days: 365 * 2)),
|
lastDate: DateTime.now().add(Duration(days: 365 * 2)),
|
||||||
);
|
);
|
||||||
if (picked != null) {
|
if (picked != null && mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_endDate = picked;
|
_endDate = picked;
|
||||||
});
|
});
|
||||||
@@ -378,17 +379,21 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
// Validation email simple
|
// Validation email simple
|
||||||
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||||
if (!emailRegex.hasMatch(email)) {
|
if (!emailRegex.hasMatch(email)) {
|
||||||
ScaffoldMessenger.of(
|
if (mounted) {
|
||||||
context,
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
).showSnackBar(SnackBar(content: Text('Email invalide')));
|
SnackBar(content: Text('Email invalide'))
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si l'email existe déjà
|
// Vérifier si l'email existe déjà
|
||||||
if (_participants.contains(email)) {
|
if (_participants.contains(email)) {
|
||||||
ScaffoldMessenger.of(
|
if (mounted) {
|
||||||
context,
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
).showSnackBar(SnackBar(content: Text('Ce participant est déjà ajouté')));
|
SnackBar(content: Text('Ce participant est déjà ajouté'))
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,9 +415,11 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_startDate == null || _endDate == null) {
|
if (_startDate == null || _endDate == null) {
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('Veuillez sélectionner les dates')),
|
SnackBar(content: Text('Veuillez sélectionner les dates')),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +431,7 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
// TODO: Implémenter la sauvegarde du voyage
|
// TODO: Implémenter la sauvegarde du voyage
|
||||||
await Future.delayed(Duration(seconds: 2)); // Simulation
|
await Future.delayed(Duration(seconds: 2)); // Simulation
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Voyage créé avec succès !'),
|
content: Text('Voyage créé avec succès !'),
|
||||||
@@ -432,17 +440,22 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Erreur lors de la création: $e'),
|
content: Text('Erreur lors de la création: $e'),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class HomeContent extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Espacement en bas pour éviter que le FAB cache le contenu
|
// Espacement en bas pour éviter que le FAB cache le contenu
|
||||||
SizedBox(height: 80),
|
const SizedBox(height: 80),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -82,7 +82,7 @@ class HomeContent extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
child: Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
),
|
),
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||||
);
|
);
|
||||||
@@ -100,7 +100,7 @@ class HomeContent extends StatelessWidget {
|
|||||||
}) {
|
}) {
|
||||||
return Card(
|
return Card(
|
||||||
elevation: 4,
|
elevation: 4,
|
||||||
margin: EdgeInsets.only(bottom: 16),
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -115,7 +115,7 @@ class HomeContent extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
height: 150,
|
height: 150,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
|
borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
@@ -131,7 +131,7 @@ class HomeContent extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(12),
|
top: Radius.circular(12),
|
||||||
),
|
),
|
||||||
color: color.withValues(alpha: 0.3),
|
color: color.withValues(alpha: 0.3),
|
||||||
@@ -148,24 +148,24 @@ class HomeContent extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
const Icon(
|
||||||
Icons.location_on,
|
Icons.location_on,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 16,
|
size: 16,
|
||||||
),
|
),
|
||||||
SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
location,
|
location,
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:location/location.dart';
|
|
||||||
|
|
||||||
class MapContent extends StatefulWidget {
|
class MapContent extends StatefulWidget {
|
||||||
const MapContent({super.key});
|
const MapContent({super.key});
|
||||||
@@ -12,130 +9,13 @@ class MapContent extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MapContentState extends State<MapContent> {
|
class _MapContentState extends State<MapContent> {
|
||||||
Location locationController = Location();
|
final LatLng _initialPosition = LatLng(48.8566, 2.3522); // Paris
|
||||||
|
|
||||||
final Completer<GoogleMapController> _mapController =
|
|
||||||
Completer<GoogleMapController>();
|
|
||||||
|
|
||||||
LatLng? currentPosition;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
//getLocationUpdate();
|
|
||||||
currentPosition = LatLng(48.8566, 2.3522); // Position par défaut (Paris)
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return GoogleMap(initialCameraPosition: CameraPosition(
|
||||||
body: SafeArea(
|
target: _initialPosition,
|
||||||
child: Padding(
|
zoom: 12,
|
||||||
padding: EdgeInsets.all(8.0),
|
));
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
TextField(
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: 'Rechercher un lieu...',
|
|
||||||
prefixIcon: Icon(Icons.search),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 50,
|
|
||||||
child: ElevatedButton(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
// TODO : Logique de recherche à implémenter
|
|
||||||
},
|
|
||||||
child: Text('Chercher'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.0),
|
|
||||||
Expanded(
|
|
||||||
child: currentPosition == null
|
|
||||||
? const Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
)
|
|
||||||
: GoogleMap(
|
|
||||||
onMapCreated: (GoogleMapController controller) =>
|
|
||||||
_mapController.complete(controller),
|
|
||||||
initialCameraPosition: CameraPosition(
|
|
||||||
target: currentPosition!,
|
|
||||||
zoom: 14.4746,
|
|
||||||
),
|
|
||||||
myLocationEnabled: true,
|
|
||||||
myLocationButtonEnabled: true,
|
|
||||||
mapType: MapType.normal,
|
|
||||||
zoomControlsEnabled: true,
|
|
||||||
markers: {
|
|
||||||
Marker(
|
|
||||||
markerId: MarkerId('currentLocation'),
|
|
||||||
position: currentPosition!,
|
|
||||||
icon: BitmapDescriptor.defaultMarkerWithHue(
|
|
||||||
BitmapDescriptor.hueAzure,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _cameraToPosition(LatLng pos) async {
|
|
||||||
final GoogleMapController controller = await _mapController.future;
|
|
||||||
CameraPosition newCameraPosition = CameraPosition(target: pos, zoom: 13);
|
|
||||||
await controller.animateCamera(
|
|
||||||
CameraUpdate.newCameraPosition(newCameraPosition),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> getLocationUpdate() async {
|
|
||||||
bool serviceEnabled;
|
|
||||||
PermissionStatus permissionGranted;
|
|
||||||
|
|
||||||
serviceEnabled = await locationController.serviceEnabled();
|
|
||||||
if (serviceEnabled) {
|
|
||||||
serviceEnabled = await locationController.requestService();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
permissionGranted = await locationController.hasPermission();
|
|
||||||
if (permissionGranted == PermissionStatus.denied) {
|
|
||||||
permissionGranted = await locationController.requestPermission();
|
|
||||||
if (permissionGranted != PermissionStatus.granted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
locationController.onLocationChanged.listen((LocationData currentLocation) {
|
|
||||||
if (currentLocation.latitude != null &&
|
|
||||||
currentLocation.longitude != null) {
|
|
||||||
setState(() {
|
|
||||||
currentPosition = LatLng(
|
|
||||||
currentLocation.latitude!,
|
|
||||||
currentLocation.longitude!,
|
|
||||||
);
|
|
||||||
_cameraToPosition(currentPosition!);
|
|
||||||
print(currentPosition);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,18 +8,18 @@ class SettingsContent extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView(
|
return ListView(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
children: [
|
children: [
|
||||||
Text(
|
const Text(
|
||||||
'Paramètres',
|
'Paramètres',
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Section Profil intégrée
|
// Section Profil intégrée
|
||||||
ProfileContent(),
|
const ProfileContent(),
|
||||||
|
|
||||||
SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Autres paramètres
|
// Autres paramètres
|
||||||
Text(
|
Text(
|
||||||
@@ -30,39 +30,39 @@ class SettingsContent extends StatelessWidget {
|
|||||||
color: Colors.grey[600],
|
color: Colors.grey[600],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.palette),
|
leading: const Icon(Icons.palette),
|
||||||
title: Text('Thème'),
|
title: const Text('Thème'),
|
||||||
subtitle: Text('Clair, sombre ou système'),
|
subtitle: const Text('Clair, sombre ou système'),
|
||||||
trailing: Icon(Icons.arrow_forward_ios),
|
trailing: const Icon(Icons.arrow_forward_ios),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => SettingsThemeContent()),
|
MaterialPageRoute(builder: (context) => const SettingsThemeContent()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.notifications),
|
leading: const Icon(Icons.notifications),
|
||||||
title: Text('Notifications'),
|
title: const Text('Notifications'),
|
||||||
trailing: Icon(Icons.arrow_forward_ios),
|
trailing: const Icon(Icons.arrow_forward_ios),
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
),
|
),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.language),
|
leading: const Icon(Icons.language),
|
||||||
title: Text('Langue'),
|
title: const Text('Langue'),
|
||||||
trailing: Icon(Icons.arrow_forward_ios),
|
trailing: const Icon(Icons.arrow_forward_ios),
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
),
|
),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.privacy_tip),
|
leading: const Icon(Icons.privacy_tip),
|
||||||
title: Text('Confidentialité'),
|
title: const Text('Confidentialité'),
|
||||||
trailing: Icon(Icons.arrow_forward_ios),
|
trailing: const Icon(Icons.arrow_forward_ios),
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -9,68 +9,93 @@ class SettingsThemeContent extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('Thème'),
|
title: const Text('Thème'),
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
),
|
),
|
||||||
body: Consumer<ThemeProvider>(
|
body: Consumer<ThemeProvider>(
|
||||||
builder: (context, themeProvider, child) {
|
builder: (context, themeProvider, child) {
|
||||||
return ListView(
|
return ListView(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Choisir le thème',
|
'Choisir le thème',
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Option Système
|
// Option Système
|
||||||
RadioListTile<ThemeMode>(
|
Card(
|
||||||
title: Text('Système'),
|
child: ListTile(
|
||||||
subtitle: Text('Suit les paramètres de votre appareil'),
|
leading: Icon(
|
||||||
value: ThemeMode.system,
|
themeProvider.themeMode == ThemeMode.system
|
||||||
groupValue: themeProvider.themeMode,
|
? Icons.radio_button_checked
|
||||||
onChanged: (ThemeMode? value) {
|
: Icons.radio_button_unchecked,
|
||||||
if (value != null) {
|
color: themeProvider.themeMode == ThemeMode.system
|
||||||
themeProvider.setThemeMode(value);
|
? Theme.of(context).colorScheme.primary
|
||||||
}
|
: null,
|
||||||
},
|
|
||||||
secondary: Icon(Icons.brightness_auto),
|
|
||||||
),
|
),
|
||||||
|
title: const Text('Système'),
|
||||||
|
subtitle: const Text('Suit les paramètres de votre appareil'),
|
||||||
|
trailing: const Icon(Icons.brightness_auto),
|
||||||
|
selected: themeProvider.themeMode == ThemeMode.system,
|
||||||
|
onTap: () {
|
||||||
|
themeProvider.setThemeMode(ThemeMode.system);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// Option Clair
|
// Option Clair
|
||||||
RadioListTile<ThemeMode>(
|
Card(
|
||||||
title: Text('Clair'),
|
child: ListTile(
|
||||||
subtitle: Text('Thème clair en permanence'),
|
leading: Icon(
|
||||||
value: ThemeMode.light,
|
themeProvider.themeMode == ThemeMode.light
|
||||||
groupValue: themeProvider.themeMode,
|
? Icons.radio_button_checked
|
||||||
onChanged: (ThemeMode? value) {
|
: Icons.radio_button_unchecked,
|
||||||
if (value != null) {
|
color: themeProvider.themeMode == ThemeMode.light
|
||||||
themeProvider.setThemeMode(value);
|
? Theme.of(context).colorScheme.primary
|
||||||
}
|
: null,
|
||||||
},
|
|
||||||
secondary: Icon(Icons.light_mode),
|
|
||||||
),
|
),
|
||||||
|
title: const Text('Clair'),
|
||||||
|
subtitle: const Text('Thème clair en permanence'),
|
||||||
|
trailing: const Icon(Icons.light_mode),
|
||||||
|
selected: themeProvider.themeMode == ThemeMode.light,
|
||||||
|
onTap: () {
|
||||||
|
themeProvider.setThemeMode(ThemeMode.light);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// Option Sombre
|
// Option Sombre
|
||||||
RadioListTile<ThemeMode>(
|
Card(
|
||||||
title: Text('Sombre'),
|
child: ListTile(
|
||||||
subtitle: Text('Thème sombre en permanence'),
|
leading: Icon(
|
||||||
value: ThemeMode.dark,
|
themeProvider.themeMode == ThemeMode.dark
|
||||||
groupValue: themeProvider.themeMode,
|
? Icons.radio_button_checked
|
||||||
onChanged: (ThemeMode? value) {
|
: Icons.radio_button_unchecked,
|
||||||
if (value != null) {
|
color: themeProvider.themeMode == ThemeMode.dark
|
||||||
themeProvider.setThemeMode(value);
|
? Theme.of(context).colorScheme.primary
|
||||||
}
|
: null,
|
||||||
|
),
|
||||||
|
title: const Text('Sombre'),
|
||||||
|
subtitle: const Text('Thème sombre en permanence'),
|
||||||
|
trailing: const Icon(Icons.dark_mode),
|
||||||
|
selected: themeProvider.themeMode == ThemeMode.dark,
|
||||||
|
onTap: () {
|
||||||
|
themeProvider.setThemeMode(ThemeMode.dark);
|
||||||
},
|
},
|
||||||
secondary: Icon(Icons.dark_mode),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
|
|
||||||
// Aperçu du thème actuel
|
// Aperçu du thème actuel
|
||||||
Card(
|
Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -78,7 +103,7 @@ class SettingsThemeContent extends StatelessWidget {
|
|||||||
'Aperçu',
|
'Aperçu',
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
@@ -87,7 +112,7 @@ class SettingsThemeContent extends StatelessWidget {
|
|||||||
: Icons.light_mode,
|
: Icons.light_mode,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
themeProvider.isDarkMode
|
themeProvider.isDarkMode
|
||||||
? 'Mode sombre actif'
|
? 'Mode sombre actif'
|
||||||
|
|||||||
@@ -15,16 +15,8 @@ class HomePage extends StatefulWidget {
|
|||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
int _currentIndex = 0;
|
int _currentIndex = 0;
|
||||||
|
|
||||||
@override
|
// Cache pour les pages créées
|
||||||
Widget build(BuildContext context) {
|
final Map<int, Widget> _pageCache = {};
|
||||||
// Définir les pages directement dans le build pour éviter les erreurs
|
|
||||||
final List<Widget> pages = [
|
|
||||||
HomeContent(), // 0
|
|
||||||
SettingsContent(), // 1
|
|
||||||
MapContent(), // 2
|
|
||||||
GroupContent(), // 3
|
|
||||||
CountContent(), // 4
|
|
||||||
];
|
|
||||||
|
|
||||||
final List<String> titles = [
|
final List<String> titles = [
|
||||||
'Mes voyages', // 0
|
'Mes voyages', // 0
|
||||||
@@ -34,9 +26,51 @@ class _HomePageState extends State<HomePage> {
|
|||||||
'Comptes', // 4
|
'Comptes', // 4
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Widget _buildPage(int index) {
|
||||||
|
// Vérifier si la page est déjà en cache
|
||||||
|
if (_pageCache.containsKey(index)) {
|
||||||
|
return _pageCache[index]!;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Créer la page seulement quand elle est demandée
|
||||||
|
Widget page;
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
page = const HomeContent();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
page = const SettingsContent();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
page = const MapContent();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
page = const GroupContent();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
page = const CountContent();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
page = const HomeContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mettre en cache la page créée
|
||||||
|
_pageCache[index] = page;
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onNavigationTap(int index) {
|
||||||
|
setState(() {
|
||||||
|
_currentIndex = index;
|
||||||
|
});
|
||||||
|
Navigator.pop(context); // Fermer le drawer
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(titles[_currentIndex]), // Debug
|
title: Text(titles[_currentIndex]),
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
),
|
),
|
||||||
@@ -48,70 +82,40 @@ class _HomePageState extends State<HomePage> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.inversePrimary,
|
color: Theme.of(context).colorScheme.inversePrimary,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: const Text(
|
||||||
"Travel Mate",
|
"Travel Mate",
|
||||||
style: TextStyle(color: Colors.white, fontSize: 24),
|
style: TextStyle(color: Colors.white, fontSize: 24),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
_buildDrawerItem(
|
||||||
leading: Icon(Icons.home),
|
icon: Icons.home,
|
||||||
title: Text("Mes voyages"),
|
title: "Mes voyages",
|
||||||
selected: _currentIndex == 0,
|
index: 0,
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = 0;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
_buildDrawerItem(
|
||||||
leading: Icon(Icons.settings),
|
icon: Icons.settings,
|
||||||
title: Text("Paramètres"),
|
title: "Paramètres",
|
||||||
selected: _currentIndex == 1,
|
index: 1,
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = 1;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
_buildDrawerItem(
|
||||||
leading: Icon(Icons.map),
|
icon: Icons.map,
|
||||||
title: Text("Carte"),
|
title: "Carte",
|
||||||
selected: _currentIndex == 2,
|
index: 2,
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = 2;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
_buildDrawerItem(
|
||||||
leading: Icon(Icons.group),
|
icon: Icons.group,
|
||||||
title: Text("Chat de groupe"),
|
title: "Chat de groupe",
|
||||||
selected: _currentIndex == 3,
|
index: 3,
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = 3;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
_buildDrawerItem(
|
||||||
leading: Icon(Icons.account_balance_wallet),
|
icon: Icons.account_balance_wallet,
|
||||||
title: Text("Comptes"),
|
title: "Comptes",
|
||||||
selected: _currentIndex == 4,
|
index: 4,
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = 4;
|
|
||||||
});
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.logout, color: Colors.red),
|
leading: const Icon(Icons.logout, color: Colors.red),
|
||||||
title: Text("Déconnexion", style: TextStyle(color: Colors.red)),
|
title: const Text("Déconnexion", style: TextStyle(color: Colors.red)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
Navigator.pushNamedAndRemoveUntil(
|
||||||
@@ -124,7 +128,38 @@ class _HomePageState extends State<HomePage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: pages[_currentIndex],
|
body: IndexedStack(
|
||||||
|
index: _currentIndex,
|
||||||
|
children: [
|
||||||
|
// Créer les pages seulement si elles sont sélectionnées
|
||||||
|
for (int i = 0; i < titles.length; i++)
|
||||||
|
if (_currentIndex == i || _pageCache.containsKey(i))
|
||||||
|
_buildPage(i)
|
||||||
|
else
|
||||||
|
Container(), // Placeholder vide
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildDrawerItem({
|
||||||
|
required IconData icon,
|
||||||
|
required String title,
|
||||||
|
required int index,
|
||||||
|
}) {
|
||||||
|
return ListTile(
|
||||||
|
leading: Icon(icon),
|
||||||
|
title: Text(title),
|
||||||
|
selected: _currentIndex == index,
|
||||||
|
selectedTileColor: Theme.of(context).colorScheme.primary.withValues(alpha: 0.1),
|
||||||
|
onTap: () => _onNavigationTap(index),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// Nettoyer le cache si nécessaire
|
||||||
|
_pageCache.clear();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
_passwordController.text,
|
_passwordController.text,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
// Naviguer vers la page d'accueil
|
// Naviguer vers la page d'accueil
|
||||||
Provider.of<UserProvider>(context, listen: false).setCurrentUser(user);
|
Provider.of<UserProvider>(context, listen: false).setCurrentUser(user);
|
||||||
@@ -70,24 +71,31 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
// Échec de la connexion
|
// Échec de la connexion
|
||||||
_showErrorMessage('Email ou mot de passe incorrect');
|
_showErrorMessage('Email ou mot de passe incorrect');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (mounted) {
|
||||||
_showErrorMessage('Erreur lors de la connexion: ${e.toString()}');
|
_showErrorMessage('Erreur lors de la connexion: ${e.toString()}');
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _showErrorMessage(String message) {
|
void _showErrorMessage(String message) {
|
||||||
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(message),
|
content: Text(message),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
duration: Duration(seconds: 3),
|
duration: const Duration(seconds: 3),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class ThemeProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
bool get isDarkMode {
|
bool get isDarkMode {
|
||||||
if (_themeMode == ThemeMode.system) {
|
if (_themeMode == ThemeMode.system) {
|
||||||
return WidgetsBinding.instance.window.platformBrightness ==
|
return WidgetsBinding.instance.platformDispatcher.platformBrightness ==
|
||||||
Brightness.dark;
|
Brightness.dark;
|
||||||
}
|
}
|
||||||
return _themeMode == ThemeMode.dark;
|
return _themeMode == ThemeMode.dark;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class TripService {
|
|||||||
final List<dynamic> jsonList = json.decode(tripsJson);
|
final List<dynamic> jsonList = json.decode(tripsJson);
|
||||||
return jsonList.map((json) => Trip.fromMap(json)).toList();
|
return jsonList.map((json) => Trip.fromMap(json)).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors du chargement des voyages: $e');
|
//print('Erreur lors du chargement des voyages: $e');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ class TripService {
|
|||||||
final jsonList = trips.map((trip) => trip.toMap()).toList();
|
final jsonList = trips.map((trip) => trip.toMap()).toList();
|
||||||
await prefs.setString(_tripsKey, json.encode(jsonList));
|
await prefs.setString(_tripsKey, json.encode(jsonList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la sauvegarde des voyages: $e');
|
//print('Erreur lors de la sauvegarde des voyages: $e');
|
||||||
throw Exception('Erreur de sauvegarde');
|
throw Exception('Erreur de sauvegarde');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ class TripService {
|
|||||||
await saveTrips(trips);
|
await saveTrips(trips);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de l\'ajout du voyage: $e');
|
//print('Erreur lors de l\'ajout du voyage: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ class TripService {
|
|||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la récupération des voyages: $e');
|
//print('Erreur lors de la récupération des voyages: $e');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ class TripService {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la mise à jour du voyage: $e');
|
//print('Erreur lors de la mise à jour du voyage: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ class TripService {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la suppression du voyage: $e');
|
//print('Erreur lors de la suppression du voyage: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class UserService {
|
|||||||
|
|
||||||
return jsonList.map((json) => User.fromMap(json)).toList();
|
return jsonList.map((json) => User.fromMap(json)).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors du chargement des utilisateurs: $e');
|
//print('Erreur lors du chargement des utilisateurs: $e');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ class UserService {
|
|||||||
final jsonList = users.map((user) => user.toMap()).toList();
|
final jsonList = users.map((user) => user.toMap()).toList();
|
||||||
await file.writeAsString(json.encode(jsonList));
|
await file.writeAsString(json.encode(jsonList));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la sauvegarde des utilisateurs: $e');
|
//print('Erreur lors de la sauvegarde des utilisateurs: $e');
|
||||||
throw Exception('Erreur de sauvegarde');
|
throw Exception('Erreur de sauvegarde');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ class UserService {
|
|||||||
await saveUsers(users);
|
await saveUsers(users);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de l\'ajout de l\'utilisateur: $e');
|
//print('Erreur lors de l\'ajout de l\'utilisateur: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ class UserService {
|
|||||||
|
|
||||||
return null; // Mot de passe incorrect
|
return null; // Mot de passe incorrect
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de l\'authentification: $e');
|
//print('Erreur lors de l\'authentification: $e');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ class UserService {
|
|||||||
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la vérification de l\'email: $e');
|
//print('Erreur lors de la vérification de l\'email: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ class UserService {
|
|||||||
final users = await loadUsers();
|
final users = await loadUsers();
|
||||||
return users.firstWhere((user) => user.id == id);
|
return users.firstWhere((user) => user.id == id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Utilisateur avec l\'ID $id non trouvé');
|
//print('Utilisateur avec l\'ID $id non trouvé');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ class UserService {
|
|||||||
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
(user) => user.email.toLowerCase() == email.toLowerCase(),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Utilisateur avec l\'email $email non trouvé');
|
//print('Utilisateur avec l\'email $email non trouvé');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ class UserService {
|
|||||||
}
|
}
|
||||||
return false; // Utilisateur non trouvé
|
return false; // Utilisateur non trouvé
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la mise à jour de l\'utilisateur: $e');
|
//print('Erreur lors de la mise à jour de l\'utilisateur: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ class UserService {
|
|||||||
}
|
}
|
||||||
return false; // Utilisateur non trouvé
|
return false; // Utilisateur non trouvé
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la suppression de l\'utilisateur: $e');
|
//print('Erreur lors de la suppression de l\'utilisateur: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ class UserService {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors du changement de mot de passe: $e');
|
//print('Erreur lors du changement de mot de passe: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ class UserService {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la réinitialisation du mot de passe: $e');
|
//print('Erreur lors de la réinitialisation du mot de passe: $e');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ class UserService {
|
|||||||
final users = await loadUsers();
|
final users = await loadUsers();
|
||||||
return users.length;
|
return users.length;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors du comptage des utilisateurs: $e');
|
//print('Erreur lors du comptage des utilisateurs: $e');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ class UserService {
|
|||||||
try {
|
try {
|
||||||
await saveUsers([]);
|
await saveUsers([]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors du vidage de la base de données: $e');
|
//print('Erreur lors du vidage de la base de données: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ class UserService {
|
|||||||
await addUser(user);
|
await addUser(user);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Erreur lors de la création des utilisateurs de test: $e');
|
//print('Erreur lors de la création des utilisateurs de test: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
google_maps_flutter: ^2.13.1
|
google_maps_flutter: ^2.5.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -66,7 +66,7 @@ flutter:
|
|||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- assets/icons/
|
- assets/icons/
|
||||||
- assets/images/
|
#- assets/images/
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|||||||
Reference in New Issue
Block a user