import 'package:flutter/material.dart'; import 'package:manager_api_new/api.dart'; import 'package:manager_app/Components/confirmation_dialog.dart'; import 'package:manager_app/Components/geometry_input_container.dart'; import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/constants.dart'; import 'showNewOrUpdateQuizQuestion.dart'; void showNewOrUpdateGuidedStep( BuildContext context, GuidedStepDTO? step, String pathId, bool isEscapeMode, Function(GuidedStepDTO) onSave, ) { GuidedStepDTO workingStep = step != null ? GuidedStepDTO.fromJson(step.toJson())! : GuidedStepDTO( title: [], description: [], quizQuestions: [], order: 0, ); // Convert EventAddressDTOGeometry to GeometryDTO via JSON for the geometry picker GeometryDTO? _toGeometryDTO(EventAddressDTOGeometry? geo) { if (geo == null) return null; return GeometryDTO.fromJson(geo.toJson()); } EventAddressDTOGeometry? _toEventGeometry(GeometryDTO? geo) { if (geo == null) return null; return EventAddressDTOGeometry.fromJson(geo.toJson()); } showDialog( context: context, builder: (BuildContext context) { return StatefulBuilder( builder: (context, setState) { final double screenWidth = MediaQuery.of(context).size.width; final double screenHeight = MediaQuery.of(context).size.height; final double dialogWidth = screenWidth * 0.75; final double contentWidth = dialogWidth - 48; final double halfWidth = (contentWidth - 20) / 2; return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Container( width: dialogWidth, constraints: BoxConstraints(maxHeight: screenHeight * 0.85), padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( step == null ? "Nouvelle Étape" : "Modifier l'Étape", style: TextStyle( color: kPrimaryColor, fontSize: 20, fontWeight: FontWeight.bold), ), SizedBox(height: 16), Flexible( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Titre + Description côte à côte Row( children: [ SizedBox( width: halfWidth, child: MultiStringInputContainer( label: "Titre :", modalLabel: "Titre de l'étape", initialValue: workingStep.title ?? [], onGetResult: (val) => setState(() => workingStep.title = val), maxLines: 1, isTitle: true, ), ), SizedBox(width: 20), SizedBox( width: halfWidth, child: MultiStringInputContainer( label: "Description :", modalLabel: "Description de l'étape", initialValue: workingStep.description ?? [], onGetResult: (val) => setState( () => workingStep.description = val), maxLines: 1, isTitle: false, ), ), ], ), Divider(height: 24), // Géométrie — conversion JSON entre les deux types GeoDTO GeometryInputContainer( label: "Emplacement de l'étape :", initialGeometry: _toGeometryDTO(workingStep.geometry), initialColor: null, onSave: (geometry, color) { setState(() { workingStep.geometry = _toEventGeometry(geometry); }); }, ), // Questions — uniquement en mode Escape Game if (isEscapeMode) ...[ Divider(height: 24), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Questions / Défis", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 15)), IconButton( icon: Icon(Icons.add_circle_outline, color: kSuccess), onPressed: () { showNewOrUpdateQuizQuestion( context, null, workingStep.id ?? "temp", isEscapeMode, (newQuestion) { setState(() { workingStep.quizQuestions = [ ...(workingStep.quizQuestions ?? []), newQuestion ]; }); }, ); }, ), ], ), if (workingStep.quizQuestions == null || workingStep.quizQuestions!.isEmpty) Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Text( "Aucune question configurée.", style: TextStyle( fontStyle: FontStyle.italic, color: Colors.grey[600]), ), ) else ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: workingStep.quizQuestions!.length, itemBuilder: (context, qIndex) { final question = workingStep.quizQuestions![qIndex]; return ListTile( dense: true, title: Text(question.label.isNotEmpty ? question.label .firstWhere( (t) => t.language == 'FR', orElse: () => question.label[0]) .value ?? "Question $qIndex" : "Question $qIndex"), subtitle: Text( "Type: ${question.validationQuestionType?.value == 2 ? 'Puzzle' : question.validationQuestionType?.value == 1 ? 'QCM' : 'Texte'}"), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: Icon(Icons.edit, size: 18, color: kPrimaryColor), onPressed: () { showNewOrUpdateQuizQuestion( context, question, workingStep.id ?? "temp", isEscapeMode, (updatedQuestion) { setState(() { workingStep.quizQuestions![ qIndex] = updatedQuestion; }); }, ); }, ), IconButton( icon: Icon(Icons.delete, size: 18, color: kError), onPressed: () { showConfirmationDialog( "Supprimer cette question ?", () {}, () => setState(() => workingStep .quizQuestions! .removeAt(qIndex)), context, ); }, ), ], ), ); }, ), ], ], ), ), ), SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ SizedBox( height: 46, child: RoundedButton( text: "Annuler", press: () => Navigator.pop(context), color: kSecond, fontSize: 15, horizontal: 24, ), ), SizedBox(width: 12), SizedBox( height: 46, child: RoundedButton( text: "Sauvegarder", press: () { onSave(workingStep); Navigator.pop(context); }, color: kPrimaryColor, fontSize: 15, horizontal: 24, ), ), ], ), ], ), ), ); }, ); }, ); }