Ajout du choix des utilisateurs sur un événement. Ajout de fichiers dans un événement. (dropzone cassée)

This commit is contained in:
2025-05-26 22:10:40 +02:00
parent 82d77e2b8d
commit 49dffff1bf
1100 changed files with 157519 additions and 113 deletions

View File

@ -6,6 +6,8 @@ import 'package:provider/provider.dart';
import 'package:em2rp/providers/local_user_provider.dart';
import 'package:em2rp/providers/event_provider.dart';
import 'package:latlong2/latlong.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:path/path.dart' as p;
class EventDetails extends StatelessWidget {
final EventModel event;
@ -139,9 +141,75 @@ class EventDetails extends StatelessWidget {
),
const SizedBox(height: 8),
Text(
'${event.address.latitude}° N, ${event.address.longitude}° E',
event.address,
style: Theme.of(context).textTheme.bodyLarge,
),
if (event.latitude != 0.0 || event.longitude != 0.0) ...[
const SizedBox(height: 4),
Text(
'${event.latitude}° N, ${event.longitude}° E',
style: Theme.of(context).textTheme.bodySmall,
),
],
if (event.documents.isNotEmpty) ...[
const SizedBox(height: 16),
Text('Documents',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: AppColors.noir, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: event.documents.map((doc) {
final fileName = doc['name'] ?? '';
final url = doc['url'] ?? '';
final ext = p.extension(fileName).toLowerCase();
IconData icon;
if ([".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"]
.contains(ext)) {
icon = Icons.image;
} else if (ext == ".pdf") {
icon = Icons.picture_as_pdf;
} else if ([
".txt",
".md",
".csv",
".json",
".xml",
".docx",
".doc",
".xls",
".xlsx",
".ppt",
".pptx"
].contains(ext)) {
icon = Icons.description;
} else {
icon = Icons.attach_file;
}
return ListTile(
leading: Icon(icon, color: Colors.blueGrey),
title: Text(fileName, overflow: TextOverflow.ellipsis),
trailing: IconButton(
icon: const Icon(Icons.download),
onPressed: () async {
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url),
mode: LaunchMode.externalApplication);
}
},
),
onTap: () async {
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url),
mode: LaunchMode.externalApplication);
}
},
contentPadding: EdgeInsets.zero,
dense: true,
);
}).toList(),
),
],
],
),
),
@ -193,6 +261,7 @@ class _EventAddDialogState extends State<EventAddDialog> {
final TextEditingController _disassemblyController = TextEditingController();
final TextEditingController _latitudeController = TextEditingController();
final TextEditingController _longitudeController = TextEditingController();
final TextEditingController _addressController = TextEditingController();
DateTime? _startDateTime;
DateTime? _endDateTime;
bool _isLoading = false;
@ -208,6 +277,7 @@ class _EventAddDialogState extends State<EventAddDialog> {
_disassemblyController.dispose();
_latitudeController.dispose();
_longitudeController.dispose();
_addressController.dispose();
super.dispose();
}
@ -233,11 +303,11 @@ class _EventAddDialogState extends State<EventAddDialog> {
disassemblyTime: int.tryParse(_disassemblyController.text) ?? 0,
eventTypeId: '', // à adapter si tu veux gérer les types
customerId: '', // à adapter si tu veux gérer les clients
address: LatLng(
double.tryParse(_latitudeController.text) ?? 0.0,
double.tryParse(_longitudeController.text) ?? 0.0,
),
address: _addressController.text.trim(),
latitude: double.tryParse(_latitudeController.text) ?? 0.0,
longitude: double.tryParse(_longitudeController.text) ?? 0.0,
workforce: [],
documents: [],
);
await eventProvider.addEvent(newEvent);
setState(() {
@ -292,24 +362,19 @@ class _EventAddDialogState extends State<EventAddDialog> {
decoration: const InputDecoration(labelText: 'Démontage (h)'),
keyboardType: TextInputType.number,
),
Row(
children: [
Expanded(
child: TextFormField(
controller: _latitudeController,
decoration: const InputDecoration(labelText: 'Latitude'),
keyboardType: TextInputType.number,
),
),
const SizedBox(width: 8),
Expanded(
child: TextFormField(
controller: _longitudeController,
decoration: const InputDecoration(labelText: 'Longitude'),
keyboardType: TextInputType.number,
),
),
],
TextFormField(
controller: _latitudeController,
decoration: const InputDecoration(labelText: 'Latitude'),
keyboardType: TextInputType.number,
),
TextFormField(
controller: _longitudeController,
decoration: const InputDecoration(labelText: 'Longitude'),
keyboardType: TextInputType.number,
),
TextFormField(
controller: _addressController,
decoration: const InputDecoration(labelText: 'Adresse'),
),
const SizedBox(height: 8),
Row(

View File

@ -88,7 +88,10 @@ class ProfilePictureWidget extends StatelessWidget {
Widget _buildIconAvatar(double radius) {
return CircleAvatar(
radius: radius,
child: Icon(Icons.account_circle, size: radius * 1.5), // Icône par défaut
child: FittedBox(
fit: BoxFit.scaleDown,
child: Icon(Icons.account_circle, size: radius * 1.5),
),
);
}
}