Add launch configuration, update API keys, and refactor UI components for better structure and performance
This commit is contained in:
@@ -5,9 +5,23 @@ class CountContent extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Count Page')),
|
||||
body: const Center(child: Text('This is the Count Page')),
|
||||
return const Center(
|
||||
child: Column(
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Chat Group Page')),
|
||||
body: const Center(child: Text('This is the Chat Group Page')),
|
||||
return const Center(
|
||||
child: Column(
|
||||
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:provider/provider.dart';
|
||||
import '../../providers/user_provider.dart';
|
||||
|
||||
|
||||
class CreateTripContent extends StatefulWidget {
|
||||
const CreateTripContent({super.key});
|
||||
@@ -350,11 +349,13 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
||||
|
||||
Future<void> _selectEndDate(BuildContext context) async {
|
||||
if (_startDate == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Veuillez d\'abord sélectionner la date de début'),
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Veuillez d\'abord sélectionner la date de début'),
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,7 +365,7 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
||||
firstDate: _startDate!,
|
||||
lastDate: DateTime.now().add(Duration(days: 365 * 2)),
|
||||
);
|
||||
if (picked != null) {
|
||||
if (picked != null && mounted) {
|
||||
setState(() {
|
||||
_endDate = picked;
|
||||
});
|
||||
@@ -378,17 +379,21 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
||||
// Validation email simple
|
||||
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||
if (!emailRegex.hasMatch(email)) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Email invalide')));
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Email invalide'))
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Vérifier si l'email existe déjà
|
||||
if (_participants.contains(email)) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Ce participant est déjà ajouté')));
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Ce participant est déjà ajouté'))
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -410,9 +415,11 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
||||
}
|
||||
|
||||
if (_startDate == null || _endDate == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Veuillez sélectionner les dates')),
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Veuillez sélectionner les dates')),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -424,25 +431,31 @@ class _CreateTripContentState extends State<CreateTripContent> {
|
||||
// TODO: Implémenter la sauvegarde du voyage
|
||||
await Future.delayed(Duration(seconds: 2)); // Simulation
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Voyage créé avec succès !'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Voyage créé avec succès !'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Erreur lors de la création: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Erreur lors de la création: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class HomeContent extends StatelessWidget {
|
||||
),
|
||||
|
||||
// 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,
|
||||
foregroundColor: Colors.white,
|
||||
child: Icon(Icons.add),
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||
);
|
||||
@@ -100,7 +100,7 @@ class HomeContent extends StatelessWidget {
|
||||
}) {
|
||||
return Card(
|
||||
elevation: 4,
|
||||
margin: EdgeInsets.only(bottom: 16),
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
@@ -115,7 +115,7 @@ class HomeContent extends StatelessWidget {
|
||||
Container(
|
||||
height: 150,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
@@ -131,7 +131,7 @@ class HomeContent extends StatelessWidget {
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
),
|
||||
color: color.withValues(alpha: 0.3),
|
||||
@@ -148,24 +148,24 @@ class HomeContent extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
const Icon(
|
||||
Icons.location_on,
|
||||
color: Colors.white,
|
||||
size: 16,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
location,
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:location/location.dart';
|
||||
|
||||
class MapContent extends StatefulWidget {
|
||||
const MapContent({super.key});
|
||||
@@ -12,130 +9,13 @@ class MapContent extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MapContentState extends State<MapContent> {
|
||||
Location locationController = Location();
|
||||
|
||||
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)
|
||||
}
|
||||
final LatLng _initialPosition = LatLng(48.8566, 2.3522); // Paris
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
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,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return GoogleMap(initialCameraPosition: CameraPosition(
|
||||
target: _initialPosition,
|
||||
zoom: 12,
|
||||
));
|
||||
}
|
||||
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
Text(
|
||||
const Text(
|
||||
'Paramètres',
|
||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Section Profil intégrée
|
||||
ProfileContent(),
|
||||
const ProfileContent(),
|
||||
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Autres paramètres
|
||||
Text(
|
||||
@@ -30,39 +30,39 @@ class SettingsContent extends StatelessWidget {
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.palette),
|
||||
title: Text('Thème'),
|
||||
subtitle: Text('Clair, sombre ou système'),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
leading: const Icon(Icons.palette),
|
||||
title: const Text('Thème'),
|
||||
subtitle: const Text('Clair, sombre ou système'),
|
||||
trailing: const Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => SettingsThemeContent()),
|
||||
MaterialPageRoute(builder: (context) => const SettingsThemeContent()),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.notifications),
|
||||
title: Text('Notifications'),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
leading: const Icon(Icons.notifications),
|
||||
title: const Text('Notifications'),
|
||||
trailing: const Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.language),
|
||||
title: Text('Langue'),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
leading: const Icon(Icons.language),
|
||||
title: const Text('Langue'),
|
||||
trailing: const Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: Icon(Icons.privacy_tip),
|
||||
title: Text('Confidentialité'),
|
||||
trailing: Icon(Icons.arrow_forward_ios),
|
||||
leading: const Icon(Icons.privacy_tip),
|
||||
title: const Text('Confidentialité'),
|
||||
trailing: const Icon(Icons.arrow_forward_ios),
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -9,68 +9,93 @@ class SettingsThemeContent extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Thème'),
|
||||
title: const Text('Thème'),
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
),
|
||||
body: Consumer<ThemeProvider>(
|
||||
builder: (context, themeProvider, child) {
|
||||
return ListView(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
Text(
|
||||
'Choisir le thème',
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Option Système
|
||||
RadioListTile<ThemeMode>(
|
||||
title: Text('Système'),
|
||||
subtitle: Text('Suit les paramètres de votre appareil'),
|
||||
value: ThemeMode.system,
|
||||
groupValue: themeProvider.themeMode,
|
||||
onChanged: (ThemeMode? value) {
|
||||
if (value != null) {
|
||||
themeProvider.setThemeMode(value);
|
||||
}
|
||||
},
|
||||
secondary: Icon(Icons.brightness_auto),
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
themeProvider.themeMode == ThemeMode.system
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
color: themeProvider.themeMode == ThemeMode.system
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
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
|
||||
RadioListTile<ThemeMode>(
|
||||
title: Text('Clair'),
|
||||
subtitle: Text('Thème clair en permanence'),
|
||||
value: ThemeMode.light,
|
||||
groupValue: themeProvider.themeMode,
|
||||
onChanged: (ThemeMode? value) {
|
||||
if (value != null) {
|
||||
themeProvider.setThemeMode(value);
|
||||
}
|
||||
},
|
||||
secondary: Icon(Icons.light_mode),
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
themeProvider.themeMode == ThemeMode.light
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
color: themeProvider.themeMode == ThemeMode.light
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: null,
|
||||
),
|
||||
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
|
||||
RadioListTile<ThemeMode>(
|
||||
title: Text('Sombre'),
|
||||
subtitle: Text('Thème sombre en permanence'),
|
||||
value: ThemeMode.dark,
|
||||
groupValue: themeProvider.themeMode,
|
||||
onChanged: (ThemeMode? value) {
|
||||
if (value != null) {
|
||||
themeProvider.setThemeMode(value);
|
||||
}
|
||||
},
|
||||
secondary: Icon(Icons.dark_mode),
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
themeProvider.themeMode == ThemeMode.dark
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
color: themeProvider.themeMode == ThemeMode.dark
|
||||
? 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);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 30),
|
||||
const SizedBox(height: 30),
|
||||
|
||||
// Aperçu du thème actuel
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -78,7 +103,7 @@ class SettingsThemeContent extends StatelessWidget {
|
||||
'Aperçu',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
@@ -87,7 +112,7 @@ class SettingsThemeContent extends StatelessWidget {
|
||||
: Icons.light_mode,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
themeProvider.isDarkMode
|
||||
? 'Mode sombre actif'
|
||||
|
||||
Reference in New Issue
Block a user