refactoring
This commit is contained in:
@@ -6,7 +6,10 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../bloc/organizations_bloc.dart';
|
||||
import '../../bloc/organizations_event.dart';
|
||||
import '../../bloc/org_types_bloc.dart';
|
||||
import '../../domain/entities/type_reference_entity.dart';
|
||||
import '../../data/models/organization_model.dart';
|
||||
import '../../../../core/di/injection_container.dart';
|
||||
|
||||
/// Dialogue de création d'organisation
|
||||
class CreateOrganizationDialog extends StatefulWidget {
|
||||
@@ -34,12 +37,20 @@ class _CreateOrganizationDialogState extends State<CreateOrganizationDialog> {
|
||||
final _objectifsController = TextEditingController();
|
||||
|
||||
// Valeurs sélectionnées
|
||||
TypeOrganization _selectedType = TypeOrganization.association;
|
||||
String? _selectedTypeCode;
|
||||
bool _accepteNouveauxMembres = true;
|
||||
late final OrgTypesBloc _orgTypesBloc;
|
||||
bool _organisationPublique = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_orgTypesBloc = sl<OrgTypesBloc>()..add(const LoadOrgTypes());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_orgTypesBloc.close();
|
||||
_nomController.dispose();
|
||||
_nomCourtController.dispose();
|
||||
_descriptionController.dispose();
|
||||
@@ -146,24 +157,39 @@ class _CreateOrganizationDialogState extends State<CreateOrganizationDialog> {
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Type d'organisation
|
||||
DropdownButtonFormField<TypeOrganization>(
|
||||
value: _selectedType,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
items: TypeOrganization.values.map((type) {
|
||||
return DropdownMenuItem(
|
||||
value: type,
|
||||
child: Text(type.displayName),
|
||||
// Type d'organisation dynamique
|
||||
BlocBuilder<OrgTypesBloc, OrgTypesState>(
|
||||
bloc: _orgTypesBloc,
|
||||
builder: (context, orgTypesState) {
|
||||
final types = orgTypesState is OrgTypesLoaded
|
||||
? orgTypesState.types
|
||||
: orgTypesState is OrgTypeSuccess
|
||||
? orgTypesState.types
|
||||
: <TypeReferenceEntity>[];
|
||||
if (orgTypesState is OrgTypesLoading || orgTypesState is OrgTypesInitial) {
|
||||
return const InputDecorator(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
child: LinearProgressIndicator(),
|
||||
);
|
||||
}
|
||||
return DropdownButtonFormField<String>(
|
||||
value: types.any((t) => t.code == _selectedTypeCode) ? _selectedTypeCode : null,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
items: types.map((type) => DropdownMenuItem<String>(
|
||||
value: type.code,
|
||||
child: Text(type.libelle),
|
||||
)).toList(),
|
||||
onChanged: (value) => setState(() => _selectedTypeCode = value),
|
||||
validator: (value) => value == null ? 'Le type est obligatoire' : null,
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedType = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -378,7 +404,7 @@ class _CreateOrganizationDialogState extends State<CreateOrganizationDialog> {
|
||||
pays: _paysController.text.isNotEmpty ? _paysController.text : null,
|
||||
siteWeb: _siteWebController.text.isNotEmpty ? _siteWebController.text : null,
|
||||
objectifs: _objectifsController.text.isNotEmpty ? _objectifsController.text : null,
|
||||
typeOrganisation: _selectedType,
|
||||
typeOrganisation: _selectedTypeCode ?? 'ASSOCIATION',
|
||||
statut: StatutOrganization.active,
|
||||
accepteNouveauxMembres: _accepteNouveauxMembres,
|
||||
organisationPublique: _organisationPublique,
|
||||
|
||||
@@ -5,7 +5,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../bloc/organizations_bloc.dart';
|
||||
import '../../bloc/organizations_event.dart';
|
||||
import '../../bloc/organizations_state.dart';
|
||||
import '../../bloc/org_types_bloc.dart';
|
||||
import '../../domain/entities/type_reference_entity.dart';
|
||||
import '../../data/models/organization_model.dart';
|
||||
import '../../../../core/di/injection_container.dart';
|
||||
|
||||
class EditOrganizationDialog extends StatefulWidget {
|
||||
final OrganizationModel organization;
|
||||
@@ -35,8 +39,10 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
late final TextEditingController _siteWebController;
|
||||
late final TextEditingController _objectifsController;
|
||||
|
||||
late TypeOrganization _selectedType;
|
||||
late String _selectedTypeCode;
|
||||
late StatutOrganization _selectedStatut;
|
||||
late final OrgTypesBloc _orgTypesBloc;
|
||||
late final OrganizationsBloc _detailBloc;
|
||||
late bool _accepteNouveauxMembres;
|
||||
late bool _organisationPublique;
|
||||
|
||||
@@ -57,14 +63,44 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
_siteWebController = TextEditingController(text: widget.organization.siteWeb ?? '');
|
||||
_objectifsController = TextEditingController(text: widget.organization.objectifs ?? '');
|
||||
|
||||
_selectedType = widget.organization.typeOrganisation;
|
||||
_selectedTypeCode = widget.organization.typeOrganisation;
|
||||
_selectedStatut = widget.organization.statut;
|
||||
_orgTypesBloc = sl<OrgTypesBloc>()..add(const LoadOrgTypes());
|
||||
_accepteNouveauxMembres = widget.organization.accepteNouveauxMembres;
|
||||
_organisationPublique = widget.organization.organisationPublique;
|
||||
|
||||
// Charge le détail complet depuis l'API (la liste retourne un DTO allégé)
|
||||
_detailBloc = sl<OrganizationsBloc>();
|
||||
if (widget.organization.id != null) {
|
||||
_detailBloc.add(LoadOrganizationById(widget.organization.id!));
|
||||
}
|
||||
}
|
||||
|
||||
void _refillForm(OrganizationModel org) {
|
||||
_nomController.text = org.nom;
|
||||
_nomCourtController.text = org.nomCourt ?? '';
|
||||
_descriptionController.text = org.description ?? '';
|
||||
_emailController.text = org.email ?? '';
|
||||
_telephoneController.text = org.telephone ?? '';
|
||||
_siteWebController.text = org.siteWeb ?? '';
|
||||
_adresseController.text = org.adresse ?? '';
|
||||
_villeController.text = org.ville ?? '';
|
||||
_codePostalController.text = org.codePostal ?? '';
|
||||
_regionController.text = org.region ?? '';
|
||||
_paysController.text = org.pays ?? '';
|
||||
_objectifsController.text = org.objectifs ?? '';
|
||||
setState(() {
|
||||
_selectedTypeCode = org.typeOrganisation;
|
||||
_selectedStatut = org.statut;
|
||||
_accepteNouveauxMembres = org.accepteNouveauxMembres;
|
||||
_organisationPublique = org.organisationPublique;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_orgTypesBloc.close();
|
||||
_detailBloc.close();
|
||||
_nomController.dispose();
|
||||
_nomCourtController.dispose();
|
||||
_descriptionController.dispose();
|
||||
@@ -82,8 +118,15 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: Container(
|
||||
return BlocListener<OrganizationsBloc, OrganizationsState>(
|
||||
bloc: _detailBloc,
|
||||
listener: (context, state) {
|
||||
if (state is OrganizationLoaded) {
|
||||
_refillForm(state.organization);
|
||||
}
|
||||
},
|
||||
child: Dialog(
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * 0.9,
|
||||
constraints: const BoxConstraints(maxHeight: 600),
|
||||
child: Column(
|
||||
@@ -149,6 +192,7 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -237,23 +281,40 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
}
|
||||
|
||||
Widget _buildTypeDropdown() {
|
||||
return DropdownButtonFormField<TypeOrganization>(
|
||||
value: _selectedType,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
items: TypeOrganization.values.map((type) {
|
||||
return DropdownMenuItem(
|
||||
value: type,
|
||||
child: Text(type.displayName),
|
||||
return BlocBuilder<OrgTypesBloc, OrgTypesState>(
|
||||
bloc: _orgTypesBloc,
|
||||
builder: (context, orgTypesState) {
|
||||
final types = orgTypesState is OrgTypesLoaded
|
||||
? orgTypesState.types
|
||||
: orgTypesState is OrgTypeSuccess
|
||||
? orgTypesState.types
|
||||
: <TypeReferenceEntity>[];
|
||||
if (orgTypesState is OrgTypesLoading || orgTypesState is OrgTypesInitial) {
|
||||
return const InputDecorator(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
child: LinearProgressIndicator(),
|
||||
);
|
||||
}
|
||||
return DropdownButtonFormField<String>(
|
||||
value: types.any((t) => t.code == _selectedTypeCode) ? _selectedTypeCode : null,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Type d\'organisation *',
|
||||
border: OutlineInputBorder(),
|
||||
prefixIcon: Icon(Icons.category),
|
||||
),
|
||||
items: types.map((type) => DropdownMenuItem<String>(
|
||||
value: type.code,
|
||||
child: Text(type.libelle),
|
||||
)).toList(),
|
||||
onChanged: (value) {
|
||||
if (value != null) setState(() => _selectedTypeCode = value);
|
||||
},
|
||||
validator: (value) => value == null ? 'Le type est obligatoire' : null,
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedType = value!;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -453,7 +514,7 @@ class _EditOrganizationDialogState extends State<EditOrganizationDialog> {
|
||||
pays: _paysController.text.isNotEmpty ? _paysController.text : null,
|
||||
siteWeb: _siteWebController.text.isNotEmpty ? _siteWebController.text : null,
|
||||
objectifs: _objectifsController.text.isNotEmpty ? _objectifsController.text : null,
|
||||
typeOrganisation: _selectedType,
|
||||
typeOrganisation: _selectedTypeCode,
|
||||
statut: _selectedStatut,
|
||||
accepteNouveauxMembres: _accepteNouveauxMembres,
|
||||
organisationPublique: _organisationPublique,
|
||||
|
||||
@@ -68,10 +68,7 @@ class OrganizationCard extends StatelessWidget {
|
||||
color: const Color(0xFF6C5CE7).withOpacity(0.1), // ColorTokens cohérent
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
organization.typeOrganisation.icon,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
child: const Icon(Icons.business_outlined, size: 18, color: Color(0xFF6C5CE7)),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
// Nom et nom court
|
||||
@@ -144,7 +141,7 @@ class OrganizationCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
organization.typeOrganisation.displayName,
|
||||
organization.typeOrganisation,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF6B7280),
|
||||
|
||||
@@ -169,7 +169,7 @@ class OrganizationFilterWidget extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<TypeOrganization?>(
|
||||
child: DropdownButton<String?>(
|
||||
value: state.typeFilter,
|
||||
hint: const Text(
|
||||
'Type',
|
||||
@@ -185,30 +185,17 @@ class OrganizationFilterWidget extends StatelessWidget {
|
||||
color: Color(0xFF374151),
|
||||
),
|
||||
items: [
|
||||
const DropdownMenuItem<TypeOrganization?>(
|
||||
const DropdownMenuItem<String?>(
|
||||
value: null,
|
||||
child: Text('Tous les types'),
|
||||
),
|
||||
...TypeOrganization.values.map((type) {
|
||||
return DropdownMenuItem<TypeOrganization?>(
|
||||
value: type,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
type.icon,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
type.displayName,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
...state.organizations
|
||||
.map((org) => org.typeOrganisation)
|
||||
.toSet()
|
||||
.map((code) => DropdownMenuItem<String?>(
|
||||
value: code,
|
||||
child: Text(code, overflow: TextOverflow.ellipsis),
|
||||
)),
|
||||
],
|
||||
onChanged: (value) {
|
||||
context.read<OrganizationsBloc>().add(
|
||||
|
||||
Reference in New Issue
Block a user