Ajout du choix des utilisateurs sur un événement. Ajout de fichiers dans un événement. (dropzone cassée)
This commit is contained in:
@ -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(
|
||||
|
@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user