@golstats/gsc-reports 1.0.83 → 1.0.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +2 -2
  2. package/dist/{FilterConditions-55d68355-DMqzcKBO-CrXvtqMe-CdAVmq_i.js → FilterConditions-55d68355-DMqzcKBO-CrXvtqMe-CBqd2V4b.js} +1 -1
  3. package/dist/{FilterField-59a73e38-CNaE03Ge-CItO--FD-DiQZZ35r.js → FilterField-59a73e38-CNaE03Ge-CItO--FD-Crm4UH60.js} +1 -1
  4. package/dist/{FilterSubcategories-a9b32cc9-_h5FCZ4r-BbuVQXya-C3HLgptU.js → FilterSubcategories-a9b32cc9-_h5FCZ4r-BbuVQXya-Cv0v2GxM.js} +1 -1
  5. package/dist/css/fonts.css +83 -83
  6. package/dist/gsc-reports.css +1 -1
  7. package/dist/gsc-reports.es.js +1 -1
  8. package/dist/gsc-reports.umd.js +129 -129
  9. package/dist/{index-CtGGl_p_.js → index-D_Ufd6mr.js} +12367 -12367
  10. package/package.json +1 -1
  11. package/src/components/elementsTemplates/ModalConfigurarContenido.vue +1341 -1332
  12. package/src/components/elementsTemplates/ModalDeleteTemplate.vue +249 -249
  13. package/src/components/elementsTemplates/ModalSoloEscritorio.vue +83 -83
  14. package/src/components/elementsTemplates/ModalduplicateTemplate.vue +300 -300
  15. package/src/components/elementsTemplates/TooltipReportOptions.vue +97 -97
  16. package/src/components/elementsTemplates/TooltipTemplateOptions.vue +168 -168
  17. package/src/components/filters.vue +935 -935
  18. package/src/components/template-report-maker/CoverSelector.vue +165 -165
  19. package/src/components/template-report-maker/ReportView.vue +66 -66
  20. package/src/components/thumbnails-reports/AnalisisPostMatchType1.vue +741 -741
  21. package/src/components/thumbnails-reports/AnalisisPostMatchType2.vue +743 -743
  22. package/src/components/thumbnails-reports/AnalisisPrematchType3.vue +173 -173
  23. package/src/components/thumbnails-reports/AnalisisPrematchType4.vue +173 -173
  24. package/src/index.js +4 -4
  25. package/src/types.d.ts +45 -45
  26. package/src/utils/dateUtils.js +52 -52
  27. package/dist/images/cancha-horizontal.jpg +0 -0
  28. package/dist/images/canchaRPH.svg +0 -30
@@ -1,1332 +1,1341 @@
1
- <template>
2
- <div class="modal-overlay">
3
- <div class="modal-content">
4
- <!-- Botón de cerrar removido -->
5
-
6
- <div class="modal-header">
7
- <div class="header-left">
8
- <img
9
- src="https://golstatsimages.blob.core.windows.net/reports-images/icn-report-white.svg"
10
- class="icon-title"
11
- alt="icono reporte blanco"
12
- />
13
- <span class="modal-title"
14
- >Generar reporte&nbsp; - &nbsp; <span class="prepartido-text">Prepartido</span></span
15
- >
16
- </div>
17
- <div class="step-counter">
18
- Paso {{ currentStep === 0 ? 1 : currentStep }} de {{ totalSteps }}
19
- </div>
20
- </div>
21
- <div class="header-separator"></div>
22
- <div class="modal-body" :class="{ transitioning: isTransitioning }">
23
- <!-- Paso 0: Configuración inicial de opciones -->
24
- <div v-if="currentStep === 0" class="step-content">
25
- <!-- Sección Fortalezas - Solo se muestra si existen Fortalezas en el template -->
26
- <div v-if="hasFortalezas" class="content-section">
27
- <h3 class="section-title">Fortalezas</h3>
28
- <div class="title-separator"></div>
29
- <p class="section-description">
30
- Este template contiene {{ fortalezasCounts.equipo }} visualizaciones de Fortalezas de
31
- tu equipo y {{ fortalezasCounts.rival }} de tu rival. ¿Cómo prefieres que se agregue
32
- este contenido?
33
- </p>
34
- <div class="content-separator"></div>
35
- <div class="radio-group">
36
- <label class="radio-option">
37
- <input
38
- type="radio"
39
- name="fortalezas"
40
- value="automatico"
41
- v-model="fortalezasOption"
42
- />
43
- <span class="radio-custom"></span>
44
- <span class="radio-label">Automáticamente</span>
45
- </label>
46
- <label class="radio-option">
47
- <input type="radio" name="fortalezas" value="manual" v-model="fortalezasOption" />
48
- <span class="radio-custom"></span>
49
- <span class="radio-label">Manualmente</span>
50
- </label>
51
- </div>
52
- </div>
53
-
54
- <!-- Separador removido -->
55
-
56
- <!-- Sección Tiros de esquina - OCULTA POR EL MOMENTO -->
57
- <!-- <div v-if="hasCorners" class="content-section">
58
- <h3 class="section-title">Tiros de esquina</h3>
59
- <div class="title-separator"></div>
60
- <p class="section-description">
61
- Este template contiene 10 visualizaciones de Tiros de esquina de tu equipo. ¿Cómo
62
- prefieres que se agregue este contenido?
63
- </p>
64
- <div class="content-separator"></div>
65
- <div class="radio-group">
66
- <label class="radio-option">
67
- <input
68
- type="radio"
69
- name="tiros-esquina"
70
- value="automatico"
71
- v-model="tirosEsquinaOption"
72
- />
73
- <span class="radio-custom"></span>
74
- <span class="radio-label">Automáticamente</span>
75
- </label>
76
- <label class="radio-option">
77
- <input
78
- type="radio"
79
- name="tiros-esquina"
80
- value="manual"
81
- v-model="tirosEsquinaOption"
82
- />
83
- <span class="radio-custom"></span>
84
- <span class="radio-label">Manualmente</span>
85
- </label>
86
- </div>
87
- </div> -->
88
- </div>
89
-
90
- <!-- Pasos dinámicos renderizados por clave -->
91
- <!-- Usamos v-show en lugar de v-if para mantener los componentes montados y preservar el estado -->
92
- <template v-if="fortalezasCounts.equipo > 0">
93
- <div v-show="buildStepMap()[currentStep] === 'fortalezasEquipo'" class="step-content">
94
- <FortalezasView
95
- key="fortalezas-equipo"
96
- v-model="selectedFortalezasEquipo"
97
- team-initials="AME"
98
- :season-id="props.partido?.season_id"
99
- :team-id="props.partido?.local || props.partido?.home_team"
100
- :rival-team-id="props.partido?.visita || props.partido?.visiting_team"
101
- :game-id="props.partido?.game_id || props.partido?.id"
102
- :token="props.token"
103
- title="Fortalezas a favor de mi equipo"
104
- :total-fortalezas="fortalezasCounts.equipo"
105
- ref="fortalezasEquipoRef"
106
- />
107
- </div>
108
- </template>
109
-
110
- <template v-if="fortalezasCounts.rival > 0">
111
- <div v-show="buildStepMap()[currentStep] === 'fortalezasRival'" class="step-content">
112
- <FortalezasView
113
- key="fortalezas-rival"
114
- v-model="selectedFortalezasRival"
115
- team-initials="RIV"
116
- :season-id="props.partido?.season_id"
117
- :team-id="props.partido?.visita || props.partido?.visiting_team"
118
- :rival-team-id="props.partido?.local || props.partido?.home_team"
119
- :game-id="props.partido?.game_id || props.partido?.id"
120
- :token="props.token"
121
- title="Fortalezas a favor del rival"
122
- :total-fortalezas="fortalezasCounts.rival"
123
- ref="fortalezasRivalRef"
124
- />
125
- </div>
126
- </template>
127
-
128
- <div v-if="buildStepMap()[currentStep] === 'cornersEquipo'" class="step-content">
129
- <TirosEsquinaView
130
- v-model="selectedCornersEquipo"
131
- :rival="false"
132
- team-initials="AME"
133
- title="Tiros de esquina en contra de mi equipo"
134
- team-logo-url="https://golstatsimages.blob.core.windows.net/teams-80/2.png"
135
- ref="cornersEquipoRef"
136
- />
137
- </div>
138
-
139
- <div v-if="buildStepMap()[currentStep] === 'cornersRival'" class="step-content">
140
- <TirosEsquinaView
141
- v-model="selectedCornersRival"
142
- :rival="true"
143
- team-initials="RIV"
144
- title="Tiros de esquina en contra del rival"
145
- team-logo-url="https://golstatsimages.blob.core.windows.net/teams-80/1.png"
146
- ref="cornersRivalRef"
147
- />
148
- </div>
149
- </div>
150
- <div class="header-separator"></div>
151
- <div class="modal-footer">
152
- <button class="back-btn" @click="goBack">
153
- <svg
154
- width="16"
155
- height="16"
156
- viewBox="0 0 16 16"
157
- fill="none"
158
- xmlns="http://www.w3.org/2000/svg"
159
- >
160
- <path
161
- d="M10 12L6 8L10 4"
162
- stroke="white"
163
- stroke-width="2"
164
- stroke-linecap="round"
165
- stroke-linejoin="round"
166
- />
167
- </svg>
168
- Regresar
169
- </button>
170
- <div class="footer-actions">
171
- <button v-if="currentStep === 0" class="cancel-btn" @click="closeModal">Cancelar</button>
172
- <button
173
- v-if="currentStep === 1 || currentStep === 2"
174
- class="cancel-btn"
175
- @click="autocompletar"
176
- >
177
- Autocompletar
178
- </button>
179
- <button
180
- class="next-btn"
181
- :class="{ disabled: !canContinue }"
182
- :disabled="!canContinue"
183
- @click="continueToNext"
184
- >
185
- {{
186
- currentStep === 0
187
- ? fortalezasOption === 'automatico'
188
- ? 'Finalizar'
189
- : 'Siguiente'
190
- : currentStep === totalSteps
191
- ? 'Finalizar'
192
- : 'Siguiente'
193
- }}
194
- </button>
195
- </div>
196
- </div>
197
- </div>
198
- </div>
199
-
200
- <!-- Modal de confirmación para regresar al paso 0 -->
201
- <div v-if="showConfirmDialog" class="modal-overlay" @click.self="cancelGoBack">
202
- <div class="modal-content confirm-dialog">
203
- <div class="modal-header">
204
- <div class="header-left">
205
- <span class="modal-title">Confirmación</span>
206
- </div>
207
- </div>
208
- <div class="header-separator"></div>
209
- <div class="modal-body">
210
- <div class="step-content">
211
- <h3 class="confirm-dialog-title">¿Estás seguro de regresar?</h3>
212
- <p class="confirm-dialog-message">Se perderá la información seleccionada</p>
213
- </div>
214
- </div>
215
- <div class="modal-footer">
216
- <div class="footer-actions">
217
- <button class="cancel-btn" @click="cancelGoBack">Cancelar</button>
218
- <button class="next-btn" @click="confirmGoBackToStep0">Confirmar</button>
219
- </div>
220
- </div>
221
- </div>
222
- </div>
223
- </template>
224
-
225
- <script setup>
226
- import { ref, defineEmits, computed, nextTick } from 'vue'
227
- import FortalezasView from './FortalezasView.vue'
228
- import TirosEsquinaView from './TirosEsquinaView.vue'
229
-
230
- const emit = defineEmits(['close', 'back', 'next'])
231
-
232
- // Props para controlar el número de pasos
233
- const props = defineProps({
234
- hasRival: {
235
- type: Boolean,
236
- default: true,
237
- },
238
- token: {
239
- type: String,
240
- required: true,
241
- },
242
- template: {
243
- type: Object,
244
- required: false,
245
- default: null,
246
- },
247
- team: {
248
- type: Number,
249
- required: false,
250
- default: null,
251
- },
252
- partido: {
253
- type: Object,
254
- required: false,
255
- default: null,
256
- },
257
- })
258
-
259
- // Función para verificar si existe un componente Fortalezas en el template
260
- function tieneComponenteFortalezas() {
261
- if (!props.template || !props.template.pages) {
262
- return false
263
- }
264
-
265
- // Iterar sobre todas las pages del template
266
- for (const page of props.template.pages) {
267
- // Verificar si la page tiene components
268
- if (page.components && Array.isArray(page.components)) {
269
- // Buscar si existe algún componente con name === 'Fortalezas' o id === 15
270
- const tieneFortalezas = page.components.some(
271
- (component) =>
272
- component.title === 'Fortalezas' ||
273
- component.id === 15 ||
274
- component.componentName === 'GSCStrengths',
275
- )
276
- if (tieneFortalezas) {
277
- return true
278
- }
279
- }
280
- }
281
-
282
- return false
283
- }
284
-
285
- // Función para contar Fortalezas del equipo propio y del rival
286
- function contarFortalezas() {
287
- console.log(
288
- '5555555555555555 Nuevo Valor al crear fortalezas:: : : :: : : : :: : : :',
289
- props.template,
290
- )
291
- if (!props.template || !props.template.pages) {
292
- return { equipo: 0, rival: 0, total: 0 }
293
- }
294
- console.log('Nuevo Valor al crear fortalezas:: : : :: : : : :: : : :', props.template)
295
-
296
- let countEquipo = 0
297
- let countRival = 0
298
-
299
- // Iterar sobre todas las pages del template
300
- for (const page of props.template.pages) {
301
- console.log('page 11 5555555555555555555555555555555555 ', page)
302
- // Verificar si la page tiene components
303
- if (page.components && Array.isArray(page.components)) {
304
- console.log('page entro')
305
- // Filtrar componentes Fortalezas
306
- const componentesFortalezas = page.components.filter(
307
- (component) =>
308
- component.componentName === 'GSCStrengths' ||
309
- component.id === 15 ||
310
- component.name === 'Fortalezas',
311
- )
312
- console.log(
313
- 'componentesFortalezas componentesFortalezas componentesFortalezas',
314
- componentesFortalezas,
315
- )
316
- // Para cada componente Fortalezas, verificar dynamicFilters
317
- for (const component of componentesFortalezas) {
318
- // Verificar si tiene dynamicFilters y es un array
319
- if (component.dynamicFilters && Array.isArray(component.dynamicFilters)) {
320
- // Verificar la posición 1 (que es un array)
321
- if (component.dynamicFilters[1]) {
322
- // Consultar la posición 0 para determinar si es equipo propio (1) o rival (2)
323
- if (component.dynamicFilters[0] === 1) {
324
- countEquipo += component.dynamicFilters[1]
325
- } else if (component.dynamicFilters[0] === 2) {
326
- countRival += component.dynamicFilters[1]
327
- } else {
328
- if (component.dynamicFilters[0] === 3) {
329
- if (component.filterMultiple.isHomeTeam) {
330
- countEquipo += component.dynamicFilters[1]
331
- } else {
332
- countRival += component.dynamicFilters[1]
333
- }
334
- }
335
- }
336
- }
337
- }
338
- }
339
- }
340
- }
341
- console.log('CONTADOR FINAL DE FORTALEZAS: ', {
342
- equipo: countEquipo,
343
- rival: countRival,
344
- total: countEquipo + countRival,
345
- })
346
- return {
347
- equipo: countEquipo,
348
- rival: countRival,
349
- total: countEquipo + countRival,
350
- }
351
- }
352
-
353
- // Computed para verificar si tiene Fortalezas
354
- const hasFortalezas = computed(() => tieneComponenteFortalezas())
355
-
356
- // Computed para obtener los conteos de Fortalezas
357
- const fortalezasCounts = computed(() => contarFortalezas())
358
-
359
- // const hasCorners = false // OCULTO POR EL MOMENTO
360
- // Estado del modal
361
- const currentStep = ref(0) // 0 = configuración inicial, luego pasos dinámicos
362
- const isTransitioning = ref(false)
363
-
364
- // Modal de confirmación para regresar al paso 0
365
- const showConfirmDialog = ref(false)
366
-
367
- // Opciones seleccionadas para cada sección
368
- const fortalezasOption = ref('manual')
369
- const tirosEsquinaOption = ref('manual')
370
-
371
- // Selecciones por vista
372
- const selectedFortalezasEquipo = ref([])
373
- const selectedFortalezasRival = ref([])
374
- const selectedCornersEquipo = ref([])
375
- const selectedCornersRival = ref([])
376
-
377
- // Calcular el número total de pasos
378
- const totalSteps = computed(() => {
379
- let steps = 0
380
-
381
- // Pasos de Fortalezas
382
- if (hasFortalezas.value && fortalezasOption.value === 'manual') {
383
- // Si hay fortalezas de equipo, agregar paso 1
384
- if (fortalezasCounts.value.equipo > 0) {
385
- steps += 1
386
- }
387
- // Si hay fortalezas de rival, agregar paso (será 2 si hay equipo, 1 si no hay)
388
- if (fortalezasCounts.value.rival > 0) {
389
- steps += 1
390
- }
391
- }
392
-
393
- // Pasos de Tiros de esquina - OCULTOS POR EL MOMENTO
394
- // if (tirosEsquinaOption.value === 'manual') {
395
- // steps += props.hasRival ? 2 : 1
396
- // }
397
-
398
- return Math.max(steps, 1)
399
- })
400
-
401
- // Verificar si se puede continuar al siguiente paso
402
- const canContinue = computed(() => {
403
- if (currentStep.value === 0) {
404
- // Si no hay Fortalezas, no se puede continuar (tirosEsquina está oculto)
405
- if (!hasFortalezas.value) {
406
- return false
407
- }
408
- // Puede continuar si está en automático o en manual
409
- return fortalezasOption.value === 'automatico' || fortalezasOption.value === 'manual'
410
- }
411
- const stepMap = buildStepMap()
412
- const key = stepMap[currentStep.value]
413
-
414
- if (key === 'fortalezasEquipo') {
415
- const ref = fortalezasEquipoRef.value
416
- if (!ref) return false
417
- const selected = selectedFortalezasEquipo.value.length
418
- const totalRequerido = fortalezasCounts.value.equipo
419
- // Obtener el total de fortalezas disponibles del componente
420
- const totalDisponibles = ref.fortalezasData?.length || 0
421
-
422
- // Puede continuar si:
423
- // 1. Selecciona el total exacto requerido
424
- // 2. O si no hay suficientes disponibles, selecciona todos los disponibles
425
- return (
426
- selected === totalRequerido ||
427
- (totalDisponibles > 0 && totalDisponibles < totalRequerido && selected === totalDisponibles)
428
- )
429
- }
430
-
431
- if (key === 'fortalezasRival') {
432
- const ref = fortalezasRivalRef.value
433
- if (!ref) return false
434
- const selected = selectedFortalezasRival.value.length
435
- const totalRequerido = fortalezasCounts.value.rival
436
- // Obtener el total de fortalezas disponibles del componente
437
- const totalDisponibles = ref.fortalezasData?.length || 0
438
-
439
- // Puede continuar si:
440
- // 1. Selecciona el total exacto requerido
441
- // 2. O si no hay suficientes disponibles, selecciona todos los disponibles
442
- return (
443
- selected === totalRequerido ||
444
- (totalDisponibles > 0 && totalDisponibles < totalRequerido && selected === totalDisponibles)
445
- )
446
- }
447
-
448
- // Pasos de corners ocultos
449
- // if (key === 'cornersEquipo') return selectedCornersEquipo.value.length > 0
450
- // if (key === 'cornersRival') return selectedCornersRival.value.length > 0
451
- return false
452
- })
453
-
454
- function buildStepMap() {
455
- const order = []
456
-
457
- // Solo agregar pasos de Fortalezas si existen en el template y está en modo manual
458
- if (hasFortalezas.value && fortalezasOption.value === 'manual') {
459
- // Si hay fortalezas de equipo, agregar paso de equipo
460
- if (fortalezasCounts.value.equipo > 0) {
461
- order.push('fortalezasEquipo')
462
- }
463
- // Si hay fortalezas de rival, agregar paso de rival
464
- if (fortalezasCounts.value.rival > 0) {
465
- order.push('fortalezasRival')
466
- }
467
- }
468
-
469
- // Pasos de Tiros de esquina - OCULTOS POR EL MOMENTO
470
- // if (tirosEsquinaOption.value === 'manual') {
471
- // order.push('cornersEquipo')
472
- // if (props.hasRival) order.push('cornersRival')
473
- // }
474
-
475
- const map = {}
476
- order.forEach((k, idx) => {
477
- map[idx + 1] = k // pasos empiezan en 1
478
- })
479
- return map
480
- }
481
-
482
- // Referencias a los componentes
483
- const fortalezasEquipoRef = ref(null)
484
- const fortalezasRivalRef = ref(null)
485
- const cornersEquipoRef = ref(null)
486
- const cornersRivalRef = ref(null)
487
-
488
- function closeModal() {
489
- emit('close')
490
- }
491
-
492
- function goBack() {
493
- if (currentStep.value > 1) {
494
- // Si estamos en paso 2 o superior, solo regresar sin borrar selecciones
495
- currentStep.value--
496
- } else if (currentStep.value === 1) {
497
- // Si estamos en paso 1 y vamos al paso 0, mostrar modal de confirmación
498
- // Verificar si hay selecciones antes de mostrar el modal
499
- const tieneSelecciones =
500
- selectedFortalezasEquipo.value.length > 0 || selectedFortalezasRival.value.length > 0
501
-
502
- if (tieneSelecciones) {
503
- showConfirmDialog.value = true
504
- } else {
505
- // Si no hay selecciones, regresar directamente
506
- currentStep.value--
507
- }
508
- } else {
509
- // Si estamos en paso 0, emitir evento back
510
- emit('back')
511
- }
512
- }
513
-
514
- function confirmGoBackToStep0() {
515
- // Limpiar todas las selecciones
516
- selectedFortalezasEquipo.value = []
517
- selectedFortalezasRival.value = []
518
- selectedCornersEquipo.value = []
519
- selectedCornersRival.value = []
520
-
521
- // Cerrar el modal de confirmación
522
- showConfirmDialog.value = false
523
-
524
- // Regresar al paso 0
525
- currentStep.value--
526
- }
527
-
528
- function cancelGoBack() {
529
- // Cerrar el modal de confirmación sin hacer nada
530
- showConfirmDialog.value = false
531
- }
532
-
533
- async function continueToNext() {
534
- if (currentStep.value === 0) {
535
- // Validar que al menos una opción esté seleccionada
536
- if (!canContinue.value) {
537
- return
538
- }
539
-
540
- // Si está en automático, finalizar directamente sin construir payload
541
- if (fortalezasOption.value === 'automatico') {
542
- // Emitir evento sin payload de strengths (se generarán automáticamente)
543
- emit('next', {
544
- fortalezas: fortalezasOption.value,
545
- tirosEsquina: tirosEsquinaOption.value,
546
- selectedFortalezasEquipo: [],
547
- selectedFortalezasRival: [],
548
- strengthsPayload: {}, // Payload vacío para modo automático
549
- })
550
- return
551
- }
552
-
553
- // Si es manual, avanzar al siguiente paso
554
- // Animar transición
555
- isTransitioning.value = true
556
- setTimeout(() => {
557
- currentStep.value++
558
- isTransitioning.value = false
559
- }, 300)
560
- } else if (currentStep.value < totalSteps.value) {
561
- // Avanzar al siguiente paso
562
- isTransitioning.value = true
563
- setTimeout(() => {
564
- currentStep.value++
565
- isTransitioning.value = false
566
- }, 300)
567
- } else {
568
- // Esperar un tick para asegurar que los refs estén disponibles
569
- await nextTick()
570
-
571
- // Construir el payload de fortalezas antes de emitir
572
- const strengthsPayload = buildStrengthsPayload()
573
- console.log('Estructura de strengths emitida:', JSON.stringify(strengthsPayload, null, 2))
574
-
575
- // Emitir evento con las opciones seleccionadas y el payload de fortalezas
576
- emit('next', {
577
- fortalezas: fortalezasOption.value,
578
- tirosEsquina: tirosEsquinaOption.value,
579
- selectedFortalezasEquipo: selectedFortalezasEquipo.value,
580
- selectedFortalezasRival: selectedFortalezasRival.value,
581
- strengthsPayload,
582
- })
583
- }
584
- }
585
-
586
- // Función para construir el payload de fortalezas según la estructura requerida
587
- function buildStrengthsPayload() {
588
- console.log('=== INICIANDO buildStrengthsPayload ===')
589
- console.log('Template:', props.template)
590
- console.log('Template pages:', props.template?.pages)
591
-
592
- if (!props.template || !props.template.pages) {
593
- console.warn('No hay template o pages')
594
- return {}
595
- }
596
-
597
- const payload = {}
598
-
599
- console.log('selectedFortalezasEquipo:', selectedFortalezasEquipo.value)
600
- console.log('selectedFortalezasRival:', selectedFortalezasRival.value)
601
- console.log('fortalezasEquipoRef:', fortalezasEquipoRef.value)
602
- console.log('fortalezasRivalRef:', fortalezasRivalRef.value)
603
-
604
- // Verificar si los refs están disponibles
605
- let equipoRef = fortalezasEquipoRef.value
606
- let rivalRef = fortalezasRivalRef.value
607
-
608
- // Debug detallado de los refs
609
- if (equipoRef) {
610
- console.log('equipoRef keys:', Object.keys(equipoRef))
611
- console.log('equipoRef.fortalezasRawData:', equipoRef.fortalezasRawData)
612
- console.log('equipoRef.fortalezasRawData type:', typeof equipoRef.fortalezasRawData)
613
-
614
- // Verificar si es un ref (tiene .value)
615
- let rawDataEquipo = equipoRef.fortalezasRawData
616
- if (rawDataEquipo && typeof rawDataEquipo === 'object' && 'value' in rawDataEquipo) {
617
- console.log('⚠️ fortalezasRawData es un ref, usando .value')
618
- rawDataEquipo = rawDataEquipo.value
619
- }
620
-
621
- console.log('rawDataEquipo después de verificar ref:', rawDataEquipo)
622
- console.log('rawDataEquipo is array:', Array.isArray(rawDataEquipo))
623
- if (Array.isArray(rawDataEquipo)) {
624
- console.log('rawDataEquipo length:', rawDataEquipo.length)
625
- if (rawDataEquipo.length > 0) {
626
- console.log('Primer elemento equipoRef:', rawDataEquipo[0])
627
- }
628
- }
629
- } else {
630
- console.error(' equipoRef NO está disponible')
631
- }
632
-
633
- if (rivalRef) {
634
- console.log('rivalRef keys:', Object.keys(rivalRef))
635
- console.log('rivalRef.fortalezasRawData:', rivalRef.fortalezasRawData)
636
- console.log('rivalRef.fortalezasRawData type:', typeof rivalRef.fortalezasRawData)
637
-
638
- // Verificar si es un ref (tiene .value)
639
- let rawDataRival = rivalRef.fortalezasRawData
640
- if (rawDataRival && typeof rawDataRival === 'object' && 'value' in rawDataRival) {
641
- console.log('⚠️ fortalezasRawData es un ref, usando .value')
642
- rawDataRival = rawDataRival.value
643
- }
644
-
645
- console.log('rawDataRival después de verificar ref:', rawDataRival)
646
- console.log('rawDataRival is array:', Array.isArray(rawDataRival))
647
- if (Array.isArray(rawDataRival)) {
648
- console.log('rawDataRival length:', rawDataRival.length)
649
- if (rawDataRival.length > 0) {
650
- console.log('Primer elemento rivalRef:', rawDataRival[0])
651
- }
652
- }
653
- } else {
654
- console.error(' rivalRef NO está disponible')
655
- }
656
-
657
- // Si los refs no están disponibles, podría ser que los componentes estén ocultos con v-show
658
- if (!equipoRef && selectedFortalezasEquipo.value.length > 0) {
659
- console.warn('⚠️ Ref de equipo no disponible, pero hay selecciones')
660
- }
661
- if (!rivalRef && selectedFortalezasRival.value.length > 0) {
662
- console.warn('⚠️ Ref de rival no disponible, pero hay selecciones')
663
- }
664
-
665
- // Obtener todas las fortalezas seleccionadas ordenadas por su orden de selección
666
- const fortalezasEquipoOrdenadas = getOrderedStrengths(selectedFortalezasEquipo.value, equipoRef)
667
- const fortalezasRivalOrdenadas = getOrderedStrengths(selectedFortalezasRival.value, rivalRef)
668
-
669
- console.log('fortalezasEquipoOrdenadas:', fortalezasEquipoOrdenadas)
670
- console.log('fortalezasRivalOrdenadas:', fortalezasRivalOrdenadas)
671
-
672
- // Contadores para rastrear qué fortalezas ya se han asignado
673
- let indexEquipo = 0
674
- let indexRival = 0
675
-
676
- // Iterar sobre todas las páginas del template
677
- props.template.pages.forEach((page, pageIndex) => {
678
- const pageNumber = pageIndex + 1 // Los índices de página empiezan en 1
679
- console.log(`\n=== Página ${pageNumber} ===`)
680
- console.log('Page components:', page.components)
681
-
682
- // Verificar si la página tiene components
683
- if (page.components && Array.isArray(page.components)) {
684
- // Buscar componentes Fortalezas - usar la misma condición que en contarFortalezas
685
- page.components.forEach((component, componentIndex) => {
686
- const esComponenteFortalezas =
687
- component.componentName === 'GSCStrengths' ||
688
- component.id === 15 ||
689
- component.name === 'Fortalezas' ||
690
- component.title === 'Fortalezas'
691
-
692
- if (esComponenteFortalezas) {
693
- const componentNumber = componentIndex + 1 // Los índices de componente empiezan en 1
694
- console.log(
695
- `\n--- Componente ${componentNumber} (Fortalezas) en página ${pageNumber} ---`,
696
- )
697
- console.log('Component:', component)
698
- console.log('Component properties:', {
699
- name: component.name,
700
- title: component.title,
701
- componentName: component.componentName,
702
- id: component.id,
703
- })
704
- console.log('dynamicFilters:', component.dynamicFilters)
705
-
706
- // Verificar dynamicFilters para determinar tipo y cantidad
707
- if (component.dynamicFilters && Array.isArray(component.dynamicFilters)) {
708
- const teamType = component.dynamicFilters[0] // 1 = equipo, 2 = rival, 3 = dinámico
709
- const cantidadRequerida = component.dynamicFilters[1] || 0 // Cantidad de fortalezas necesarias
710
-
711
- console.log(
712
- `Tipo: ${teamType === 1 ? 'Equipo' : teamType === 2 ? 'Rival' : 'Dinámico (3)'}, Cantidad requerida: ${cantidadRequerida}`,
713
- )
714
-
715
- // Obtener las fortalezas según el tipo
716
- let fortalezasAsignar = []
717
- let fortalezasOrdenadas = []
718
- let teamId = props.team
719
-
720
- if (teamType === 1) {
721
- // Fortalezas de equipo
722
- fortalezasOrdenadas = fortalezasEquipoOrdenadas
723
- console.log(
724
- `Equipo: Total ordenadas=${fortalezasOrdenadas.length}, index=${indexEquipo}, cantidad requerida=${cantidadRequerida}`,
725
- )
726
- // Tomar las siguientes N fortalezas (donde N = cantidadRequerida)
727
- if (fortalezasOrdenadas.length > indexEquipo) {
728
- fortalezasAsignar = fortalezasOrdenadas.slice(
729
- indexEquipo,
730
- indexEquipo + cantidadRequerida,
731
- )
732
- console.log(
733
- `Index equipo: ${indexEquipo}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
734
- )
735
- } else {
736
- console.warn(
737
- `No hay suficientes fortalezas de equipo. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexEquipo}`,
738
- )
739
- }
740
- indexEquipo += cantidadRequerida
741
- teamId = props.partido?.local || props.partido?.home_team || props.team
742
- } else if (teamType === 2) {
743
- // Fortalezas de rival
744
- fortalezasOrdenadas = fortalezasRivalOrdenadas
745
- console.log(
746
- `Rival: Total ordenadas=${fortalezasOrdenadas.length}, index=${indexRival}, cantidad requerida=${cantidadRequerida}`,
747
- )
748
- // Tomar las siguientes N fortalezas (donde N = cantidadRequerida)
749
- if (fortalezasOrdenadas.length > indexRival) {
750
- fortalezasAsignar = fortalezasOrdenadas.slice(
751
- indexRival,
752
- indexRival + cantidadRequerida,
753
- )
754
- console.log(
755
- `Index rival: ${indexRival}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
756
- )
757
- } else {
758
- console.warn(
759
- `No hay suficientes fortalezas de rival. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexRival}`,
760
- )
761
- }
762
- indexRival += cantidadRequerida
763
- teamId = props.partido?.visita || props.partido?.visiting_team
764
- } else if (teamType === 3) {
765
- // Tipo dinámico: depende de filterMultiple.isHomeTeam
766
- if (component.filterMultiple && component.filterMultiple.isHomeTeam) {
767
- // Es equipo
768
- fortalezasOrdenadas = fortalezasEquipoOrdenadas
769
- console.log(
770
- `Dinámico (Equipo): Total ordenadas=${fortalezasOrdenadas.length}, index=${indexEquipo}, cantidad requerida=${cantidadRequerida}`,
771
- )
772
- if (fortalezasOrdenadas.length > indexEquipo) {
773
- fortalezasAsignar = fortalezasOrdenadas.slice(
774
- indexEquipo,
775
- indexEquipo + cantidadRequerida,
776
- )
777
- console.log(
778
- `Index equipo: ${indexEquipo}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
779
- )
780
- } else {
781
- console.warn(
782
- `No hay suficientes fortalezas de equipo. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexEquipo}`,
783
- )
784
- }
785
- indexEquipo += cantidadRequerida
786
- teamId = props.partido?.local || props.partido?.home_team || props.team
787
- } else {
788
- // Es rival
789
- fortalezasOrdenadas = fortalezasRivalOrdenadas
790
- console.log(
791
- `Dinámico (Rival): Total ordenadas=${fortalezasOrdenadas.length}, index=${indexRival}, cantidad requerida=${cantidadRequerida}`,
792
- )
793
- if (fortalezasOrdenadas.length > indexRival) {
794
- fortalezasAsignar = fortalezasOrdenadas.slice(
795
- indexRival,
796
- indexRival + cantidadRequerida,
797
- )
798
- console.log(
799
- `Index rival: ${indexRival}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
800
- )
801
- } else {
802
- console.warn(
803
- `No hay suficientes fortalezas de rival. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexRival}`,
804
- )
805
- }
806
- indexRival += cantidadRequerida
807
- teamId = props.partido?.visita || props.partido?.visiting_team
808
- }
809
- }
810
-
811
- console.log('fortalezasAsignar:', fortalezasAsignar)
812
-
813
- // Si hay fortalezas para asignar, agregarlas al payload
814
- if (fortalezasAsignar.length > 0) {
815
- // Inicializar la estructura si no existe
816
- if (!payload[pageNumber]) {
817
- payload[pageNumber] = {}
818
- }
819
- if (!payload[pageNumber][componentNumber]) {
820
- payload[pageNumber][componentNumber] = []
821
- }
822
-
823
- // Agregar las fortalezas con su información completa
824
- fortalezasAsignar.forEach((strength, index) => {
825
- payload[pageNumber][componentNumber].push({
826
- team_id: teamId,
827
- ranking_type: strength.ranking_type || 1,
828
- precondition_id: strength.precondition_id || null,
829
- order: index + 1,
830
- name: strength.name,
831
- category_type: strength.category_type || 1,
832
- total: strength.total || 0,
833
- is_relevant: strength.is_relevant || 0,
834
- league_ranking: strength.league_ranking || 0,
835
- categories: Array.isArray(strength.categories)
836
- ? strength.categories
837
- : [strength.categories],
838
- team_contribution: strength.team_contribution || 0,
839
- })
840
- })
841
- console.log(
842
- `✓ Agregadas ${fortalezasAsignar.length} fortalezas al payload para componente ${componentNumber} en página ${pageNumber}`,
843
- )
844
- console.log(
845
- `Payload actual para página ${pageNumber}:`,
846
- JSON.stringify(payload[pageNumber], null, 2),
847
- )
848
- } else {
849
- console.warn(
850
- `⚠️ No hay fortalezas para asignar al componente ${componentNumber} en página ${pageNumber}. IndexEquipo: ${indexEquipo}, IndexRival: ${indexRival}`,
851
- )
852
- }
853
- } else {
854
- console.warn(
855
- `⚠️ Componente ${componentIndex + 1} en página ${pageNumber} no tiene dynamicFilters válido`,
856
- )
857
- console.warn('Component:', component)
858
- }
859
- }
860
- })
861
- console.log(
862
- `\n✓ Página ${pageNumber} procesada. Componentes de Fortalezas encontrados y procesados.`,
863
- )
864
- }
865
- })
866
-
867
- console.log('\n=== PAYLOAD FINAL ===')
868
- console.log(JSON.stringify(payload, null, 2))
869
- return payload
870
- }
871
-
872
- // Función auxiliar para obtener las fortalezas en el mismo orden que fueron seleccionadas
873
- // Los IDs ya vienen en el orden correcto, solo necesitamos obtener los objetos completos
874
- function getOrderedStrengths(selectedIds, fortalezasViewRef) {
875
- console.log('=== getOrderedStrengths INICIO ===')
876
- console.log('selectedIds (orden de selección):', selectedIds)
877
- console.log('fortalezasViewRef existe?:', !!fortalezasViewRef)
878
-
879
- if (!selectedIds || selectedIds.length === 0) {
880
- console.warn('No hay IDs seleccionados')
881
- return []
882
- }
883
-
884
- if (!fortalezasViewRef) {
885
- console.warn('Ref no disponible')
886
- return []
887
- }
888
-
889
- // Obtener fortalezasRawData, verificando si es un ref
890
- let fortalezasRawData = fortalezasViewRef.fortalezasRawData
891
- if (!fortalezasRawData) {
892
- console.warn('fortalezasRawData no está disponible en el ref')
893
- return []
894
- }
895
-
896
- // Si es un ref, acceder a su .value
897
- if (fortalezasRawData && typeof fortalezasRawData === 'object' && 'value' in fortalezasRawData) {
898
- console.log('⚠️ fortalezasRawData es un ref, accediendo a .value')
899
- fortalezasRawData = fortalezasRawData.value
900
- }
901
-
902
- if (!Array.isArray(fortalezasRawData)) {
903
- console.warn('fortalezasRawData no es un array:', typeof fortalezasRawData, fortalezasRawData)
904
- return []
905
- }
906
-
907
- if (fortalezasRawData.length === 0) {
908
- console.warn('fortalezasRawData está vacío')
909
- return []
910
- }
911
-
912
- console.log('fortalezasRawData length:', fortalezasRawData.length)
913
- console.log('Primeras 2 fortalezas raw:', fortalezasRawData.slice(0, 2))
914
-
915
- // Obtener las fortalezas en el mismo orden que fueron seleccionadas (sin reordenar)
916
- // El orden ya está dado por selectedIds, solo necesitamos buscar y devolver el objeto completo
917
- const selectedStrengths = selectedIds
918
- .map((id) => {
919
- console.log(`Buscando ID: ${id} (tipo: ${typeof id})`)
920
-
921
- // Buscar en los datos raw por categories (que es el id que usamos)
922
- const strength = fortalezasRawData.find((item) => {
923
- // Comparar tanto como número como string
924
- const match =
925
- item.categories === id ||
926
- item.categories === Number(id) ||
927
- String(item.categories) === String(id)
928
- if (!match && fortalezasRawData.indexOf(item) < 3) {
929
- console.log(
930
- ` Comparando: item.categories=${item.categories} (${typeof item.categories}) vs id=${id} (${typeof id})`,
931
- )
932
- }
933
- return match
934
- })
935
-
936
- if (strength) {
937
- console.log(`✓ Encontrada: ${strength.name} (categories: ${strength.categories})`)
938
- return strength
939
- }
940
-
941
- console.warn(`✗ No encontrada con categories = ${id}, intentando por id`)
942
- // Intentar buscar también por id si categories no funciona
943
- const strengthById = fortalezasRawData.find(
944
- (item) => item.id === id || item.id === Number(id) || String(item.id) === String(id),
945
- )
946
- if (strengthById) {
947
- console.log(`✓ Encontrada por id: ${strengthById.name}`)
948
- return strengthById
949
- }
950
-
951
- console.error(`✗✗ No se encontró fortaleza con id/categories = ${id}`)
952
- return null
953
- })
954
- .filter(Boolean) // Filtrar los que no se encontraron
955
-
956
- console.log(
957
- `selectedStrengths (${selectedStrengths.length} de ${selectedIds.length} encontradas):`,
958
- selectedStrengths,
959
- )
960
- console.log('=== getOrderedStrengths FIN ===')
961
- return selectedStrengths
962
- }
963
-
964
- function autocompletar() {
965
- const stepMap = buildStepMap()
966
- const key = stepMap[currentStep.value]
967
- if (key === 'fortalezasEquipo' && fortalezasEquipoRef.value)
968
- return fortalezasEquipoRef.value.autocompletar()
969
- if (key === 'fortalezasRival' && fortalezasRivalRef.value)
970
- return fortalezasRivalRef.value.autocompletar()
971
- if (key === 'cornersEquipo' && cornersEquipoRef.value)
972
- return cornersEquipoRef.value.autocompletar()
973
- if (key === 'cornersRival' && cornersRivalRef.value) return cornersRivalRef.value.autocompletar()
974
- }
975
- </script>
976
-
977
- <style scoped>
978
- .modal-overlay {
979
- position: fixed;
980
- top: 0;
981
- left: 0;
982
- width: 100vw;
983
- height: 100vh;
984
- background: rgba(0, 0, 0, 0.45);
985
- display: flex;
986
- align-items: center;
987
- justify-content: center;
988
- z-index: 3300;
989
- }
990
-
991
- .modal-content {
992
- width: 464px;
993
- background: #2e3b46;
994
- border-radius: 10px;
995
- box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.18);
996
- padding: 0;
997
- position: relative;
998
- display: flex;
999
- flex-direction: column;
1000
- font-family: 'Poppins-Medium', 'Montserrat', sans-serif;
1001
- }
1002
-
1003
- /* Estilos del botón de cerrar removidos */
1004
-
1005
- .header-separator {
1006
- width: 100%;
1007
- height: 1px;
1008
- border-bottom: dashed 1px #58626b;
1009
- margin: 12px 0 0 0;
1010
- }
1011
-
1012
- .modal-header {
1013
- display: flex;
1014
- align-items: center;
1015
- justify-content: space-between;
1016
- padding: 20px 24px 0 24px;
1017
- }
1018
-
1019
- .header-left {
1020
- display: flex;
1021
- align-items: center;
1022
- gap: 8px;
1023
- }
1024
-
1025
- .step-counter {
1026
- font-family: Poppins-Medium;
1027
- font-size: 12px;
1028
- font-weight: 500;
1029
- color: rgba(255, 255, 255, 0.7);
1030
- }
1031
-
1032
- .icon-title {
1033
- width: 16px;
1034
- height: 16px;
1035
- }
1036
-
1037
- .modal-title {
1038
- font-family: Poppins-Medium;
1039
- font-size: 14px;
1040
- font-weight: 500;
1041
- font-stretch: normal;
1042
- font-style: normal;
1043
- line-height: 1.5;
1044
- letter-spacing: normal;
1045
- text-align: left;
1046
- color: #fff;
1047
- }
1048
-
1049
- .prepartido-text {
1050
- font-family: 'Poppins-Regular', 'BebasNeue', sans-serif;
1051
- font-weight: 400;
1052
- opacity: 0.7;
1053
- letter-spacing: 1px;
1054
- }
1055
-
1056
- .modal-body {
1057
- flex: 1;
1058
- display: flex;
1059
- flex-direction: column;
1060
- padding: 12px 24px 0 24px;
1061
- margin-bottom: 17px;
1062
- margin-top: 5px;
1063
- gap: 0;
1064
- position: relative;
1065
- overflow: hidden;
1066
- }
1067
-
1068
- .step-content {
1069
- transition: transform 0.3s ease-in-out;
1070
- }
1071
-
1072
- .modal-body.transitioning .step-content {
1073
- transform: translateX(-100%);
1074
- }
1075
-
1076
- .fortalezas-view {
1077
- transform: translateX(100%);
1078
- animation: slideIn 0.3s ease-in-out forwards;
1079
- }
1080
-
1081
- @keyframes slideIn {
1082
- from {
1083
- transform: translateX(100%);
1084
- }
1085
- to {
1086
- transform: translateX(0);
1087
- }
1088
- }
1089
-
1090
- .content-section {
1091
- background: none;
1092
- border: solid 1px rgba(255, 255, 255, 0.4);
1093
- padding: 12px 20px 20px 20px;
1094
- margin-bottom: 0;
1095
- border-radius: 8px;
1096
- }
1097
-
1098
- .content-section:first-child {
1099
- margin-bottom: 20px;
1100
- }
1101
-
1102
- .title-separator {
1103
- width: 100%;
1104
- height: 1px;
1105
- border-top: 1px dashed rgba(255, 255, 255, 0.3);
1106
- margin: 8px 0 12px 0;
1107
- margin-left: -20px;
1108
- margin-right: -20px;
1109
- width: calc(100% + 40px);
1110
- }
1111
-
1112
- .content-separator {
1113
- width: 100%;
1114
- height: 1px;
1115
- border-top: 1px dashed rgba(255, 255, 255, 0.3);
1116
- margin: 12px 0 16px 0;
1117
- margin-left: -20px;
1118
- margin-right: -20px;
1119
- width: calc(100% + 40px);
1120
- }
1121
-
1122
- .section-title {
1123
- font-family: Poppins-Medium;
1124
- font-size: 14px;
1125
- font-weight: 600;
1126
- opacity: 0.9;
1127
- color: #fff;
1128
- margin: 0 0 12px 0;
1129
- }
1130
-
1131
- .section-description {
1132
- font-family: Poppins-Regular;
1133
- font-size: 12px;
1134
- line-height: 1.4;
1135
- opacity: 0.7;
1136
- color: #fff;
1137
- margin: 0 0 13px 0;
1138
- }
1139
-
1140
- .radio-group {
1141
- display: flex;
1142
- gap: 24px;
1143
- justify-content: center;
1144
- }
1145
-
1146
- .radio-option {
1147
- display: flex;
1148
- align-items: center;
1149
- gap: 8px;
1150
- cursor: pointer;
1151
- user-select: none;
1152
- }
1153
-
1154
- .radio-option input[type='radio'] {
1155
- display: none;
1156
- }
1157
-
1158
- .radio-custom {
1159
- width: 20px;
1160
- height: 20px;
1161
- border: 1px solid #fff;
1162
- border-radius: 50%;
1163
- position: relative;
1164
- transition: all 0.2s ease;
1165
- flex-shrink: 0;
1166
- }
1167
-
1168
- .radio-option input[type='radio']:checked + .radio-custom {
1169
- border-color: #fff; /* mantiene el aro blanco */
1170
- background-color: transparent; /* sin relleno, solo punto central */
1171
- }
1172
-
1173
- .radio-option input[type='radio']:checked + .radio-custom::after {
1174
- content: '';
1175
- position: absolute;
1176
- top: 50%;
1177
- left: 50%;
1178
- transform: translate(-50%, -50%);
1179
- width: 10px;
1180
- height: 10px;
1181
- background-color: #cbee6b; /* punto verde */
1182
- border-radius: 50%;
1183
- }
1184
-
1185
- /* Cuando el radio está seleccionado, la etiqueta pierde la opacidad */
1186
- .radio-option input[type='radio']:checked + .radio-custom + .radio-label {
1187
- opacity: 0.9;
1188
- }
1189
-
1190
- .radio-label {
1191
- font-family: Poppins-Regular;
1192
- font-size: 13px;
1193
- color: #fff;
1194
- opacity: 0.7;
1195
- }
1196
-
1197
- /* Estilos del separador removidos */
1198
-
1199
- .modal-footer {
1200
- display: flex;
1201
- justify-content: space-between;
1202
- align-items: center;
1203
- padding: 0 24px 12px 24px;
1204
- margin-top: 13px;
1205
- }
1206
-
1207
- .footer-actions {
1208
- display: flex;
1209
- align-items: center;
1210
- }
1211
-
1212
- .back-btn {
1213
- background: none;
1214
- border: none;
1215
- color: #fff;
1216
- font-size: 14px;
1217
- font-family: Poppins-Medium;
1218
- display: flex;
1219
- align-items: center;
1220
- gap: 4px;
1221
- cursor: pointer;
1222
- opacity: 0.7;
1223
- padding: 8px 0;
1224
- transition: opacity 0.2s;
1225
- }
1226
-
1227
- .back-btn:hover {
1228
- opacity: 1;
1229
- }
1230
-
1231
- .cancel-btn {
1232
- background: none;
1233
- border: none;
1234
- color: #b0bec5;
1235
- font-size: 14.9px;
1236
- font-family: Poppins-Medium;
1237
- height: 30px;
1238
- border-radius: 64px;
1239
- display: flex;
1240
- align-items: center;
1241
- justify-content: center;
1242
- cursor: pointer;
1243
- padding: 0 18px;
1244
- transition: color 0.2s;
1245
- text-decoration: underline;
1246
- }
1247
-
1248
- .cancel-btn:hover {
1249
- color: #fff;
1250
- }
1251
-
1252
- .next-btn {
1253
- width: 107px;
1254
- height: 30px;
1255
- border-radius: 79.2px;
1256
- -webkit-backdrop-filter: blur(19.8px);
1257
- backdrop-filter: blur(19.8px);
1258
- border: solid 1px #cbee6b;
1259
- background-color: rgba(255, 255, 255, 0.06);
1260
- font-family: Poppins-Medium;
1261
- font-size: 14.9px;
1262
- font-weight: 500;
1263
- color: #fff;
1264
- cursor: pointer;
1265
- transition: background 0.2s;
1266
- display: flex;
1267
- align-items: center;
1268
- justify-content: center;
1269
- }
1270
-
1271
- .next-btn:hover {
1272
- background-color: rgba(255, 255, 255, 0.12);
1273
- }
1274
-
1275
- .next-btn.disabled {
1276
- opacity: 0.5;
1277
- cursor: not-allowed;
1278
- }
1279
-
1280
- .next-btn.disabled:hover {
1281
- background-color: rgba(255, 255, 255, 0.06);
1282
- }
1283
-
1284
- /* Estilos para el modal de confirmación */
1285
- .confirm-dialog {
1286
- width: 380px;
1287
- max-width: 90%;
1288
- }
1289
-
1290
- /* Asegurar que el overlay del modal de confirmación esté por encima del modal principal */
1291
- .modal-overlay:has(.confirm-dialog) {
1292
- z-index: 3400;
1293
- }
1294
-
1295
- .confirm-dialog .modal-header {
1296
- justify-content: center;
1297
- }
1298
-
1299
- .confirm-dialog .modal-body {
1300
- text-align: center;
1301
- }
1302
-
1303
- .confirm-dialog-title {
1304
- font-family: Poppins-Medium;
1305
- font-size: 16px;
1306
- font-weight: 500;
1307
- color: #fff;
1308
- margin: 0 0 12px 0;
1309
- text-align: center;
1310
- }
1311
-
1312
- .confirm-dialog-message {
1313
- font-family: Poppins-Regular;
1314
- font-size: 14px;
1315
- color: rgba(255, 255, 255, 0.7);
1316
- margin: 0;
1317
- text-align: center;
1318
- line-height: 1.5;
1319
- }
1320
-
1321
- .confirm-dialog .modal-footer {
1322
- justify-content: center;
1323
- }
1324
-
1325
- .confirm-dialog .footer-actions {
1326
- width: 100%;
1327
- justify-content: center;
1328
- gap: 12px;
1329
- }
1330
-
1331
- /* Estilos para la vista de fortalezas movidos al componente FortalezasView.vue */
1332
- </style>
1
+ <template>
2
+ <div class="modal-overlay">
3
+ <div class="modal-content">
4
+ <!-- Botón de cerrar removido -->
5
+
6
+ <div class="modal-header">
7
+ <div class="header-left">
8
+ <img
9
+ src="https://golstatsimages.blob.core.windows.net/reports-images/icn-report-white.svg"
10
+ class="icon-title"
11
+ alt="icono reporte blanco"
12
+ />
13
+ <span class="modal-title"
14
+ >Generar reporte&nbsp; - &nbsp;
15
+ <span class="prepartido-text">{{ tipoReporteTexto }}</span></span
16
+ >
17
+ </div>
18
+ <div class="step-counter">
19
+ Paso {{ currentStep === 0 ? 1 : currentStep }} de {{ totalSteps }}
20
+ </div>
21
+ </div>
22
+ <div class="header-separator"></div>
23
+ <div class="modal-body" :class="{ transitioning: isTransitioning }">
24
+ <!-- Paso 0: Configuración inicial de opciones -->
25
+ <div v-if="currentStep === 0" class="step-content">
26
+ <!-- Sección Fortalezas - Solo se muestra si existen Fortalezas en el template -->
27
+ <div v-if="hasFortalezas" class="content-section">
28
+ <h3 class="section-title">Fortalezas</h3>
29
+ <div class="title-separator"></div>
30
+ <p class="section-description">
31
+ Este template contiene {{ fortalezasCounts.equipo }} visualizaciones de Fortalezas de
32
+ tu equipo y {{ fortalezasCounts.rival }} de tu rival. ¿Cómo prefieres que se agregue
33
+ este contenido?
34
+ </p>
35
+ <div class="content-separator"></div>
36
+ <div class="radio-group">
37
+ <label class="radio-option">
38
+ <input
39
+ type="radio"
40
+ name="fortalezas"
41
+ value="automatico"
42
+ v-model="fortalezasOption"
43
+ />
44
+ <span class="radio-custom"></span>
45
+ <span class="radio-label">Automáticamente</span>
46
+ </label>
47
+ <label class="radio-option">
48
+ <input type="radio" name="fortalezas" value="manual" v-model="fortalezasOption" />
49
+ <span class="radio-custom"></span>
50
+ <span class="radio-label">Manualmente</span>
51
+ </label>
52
+ </div>
53
+ </div>
54
+
55
+ <!-- Separador removido -->
56
+
57
+ <!-- Sección Tiros de esquina - OCULTA POR EL MOMENTO -->
58
+ <!-- <div v-if="hasCorners" class="content-section">
59
+ <h3 class="section-title">Tiros de esquina</h3>
60
+ <div class="title-separator"></div>
61
+ <p class="section-description">
62
+ Este template contiene 10 visualizaciones de Tiros de esquina de tu equipo. ¿Cómo
63
+ prefieres que se agregue este contenido?
64
+ </p>
65
+ <div class="content-separator"></div>
66
+ <div class="radio-group">
67
+ <label class="radio-option">
68
+ <input
69
+ type="radio"
70
+ name="tiros-esquina"
71
+ value="automatico"
72
+ v-model="tirosEsquinaOption"
73
+ />
74
+ <span class="radio-custom"></span>
75
+ <span class="radio-label">Automáticamente</span>
76
+ </label>
77
+ <label class="radio-option">
78
+ <input
79
+ type="radio"
80
+ name="tiros-esquina"
81
+ value="manual"
82
+ v-model="tirosEsquinaOption"
83
+ />
84
+ <span class="radio-custom"></span>
85
+ <span class="radio-label">Manualmente</span>
86
+ </label>
87
+ </div>
88
+ </div> -->
89
+ </div>
90
+
91
+ <!-- Pasos dinámicos renderizados por clave -->
92
+ <!-- Usamos v-show en lugar de v-if para mantener los componentes montados y preservar el estado -->
93
+ <template v-if="fortalezasCounts.equipo > 0">
94
+ <div v-show="buildStepMap()[currentStep] === 'fortalezasEquipo'" class="step-content">
95
+ <FortalezasView
96
+ key="fortalezas-equipo"
97
+ v-model="selectedFortalezasEquipo"
98
+ team-initials="AME"
99
+ :season-id="props.partido?.season_id"
100
+ :team-id="props.partido?.local || props.partido?.home_team"
101
+ :rival-team-id="props.partido?.visita || props.partido?.visiting_team"
102
+ :game-id="props.partido?.game_id || props.partido?.id"
103
+ :token="props.token"
104
+ title="Fortalezas a favor de mi equipo"
105
+ :total-fortalezas="fortalezasCounts.equipo"
106
+ ref="fortalezasEquipoRef"
107
+ />
108
+ </div>
109
+ </template>
110
+
111
+ <template v-if="fortalezasCounts.rival > 0">
112
+ <div v-show="buildStepMap()[currentStep] === 'fortalezasRival'" class="step-content">
113
+ <FortalezasView
114
+ key="fortalezas-rival"
115
+ v-model="selectedFortalezasRival"
116
+ team-initials="RIV"
117
+ :season-id="props.partido?.season_id"
118
+ :team-id="props.partido?.visita || props.partido?.visiting_team"
119
+ :rival-team-id="props.partido?.local || props.partido?.home_team"
120
+ :game-id="props.partido?.game_id || props.partido?.id"
121
+ :token="props.token"
122
+ title="Fortalezas a favor del rival"
123
+ :total-fortalezas="fortalezasCounts.rival"
124
+ ref="fortalezasRivalRef"
125
+ />
126
+ </div>
127
+ </template>
128
+
129
+ <div v-if="buildStepMap()[currentStep] === 'cornersEquipo'" class="step-content">
130
+ <TirosEsquinaView
131
+ v-model="selectedCornersEquipo"
132
+ :rival="false"
133
+ team-initials="AME"
134
+ title="Tiros de esquina en contra de mi equipo"
135
+ team-logo-url="https://golstatsimages.blob.core.windows.net/teams-80/2.png"
136
+ ref="cornersEquipoRef"
137
+ />
138
+ </div>
139
+
140
+ <div v-if="buildStepMap()[currentStep] === 'cornersRival'" class="step-content">
141
+ <TirosEsquinaView
142
+ v-model="selectedCornersRival"
143
+ :rival="true"
144
+ team-initials="RIV"
145
+ title="Tiros de esquina en contra del rival"
146
+ team-logo-url="https://golstatsimages.blob.core.windows.net/teams-80/1.png"
147
+ ref="cornersRivalRef"
148
+ />
149
+ </div>
150
+ </div>
151
+ <div class="header-separator"></div>
152
+ <div class="modal-footer">
153
+ <button class="back-btn" @click="goBack">
154
+ <svg
155
+ width="16"
156
+ height="16"
157
+ viewBox="0 0 16 16"
158
+ fill="none"
159
+ xmlns="http://www.w3.org/2000/svg"
160
+ >
161
+ <path
162
+ d="M10 12L6 8L10 4"
163
+ stroke="white"
164
+ stroke-width="2"
165
+ stroke-linecap="round"
166
+ stroke-linejoin="round"
167
+ />
168
+ </svg>
169
+ Regresar
170
+ </button>
171
+ <div class="footer-actions">
172
+ <button v-if="currentStep === 0" class="cancel-btn" @click="closeModal">Cancelar</button>
173
+ <button
174
+ v-if="currentStep === 1 || currentStep === 2"
175
+ class="cancel-btn"
176
+ @click="autocompletar"
177
+ >
178
+ Autocompletar
179
+ </button>
180
+ <button
181
+ class="next-btn"
182
+ :class="{ disabled: !canContinue }"
183
+ :disabled="!canContinue"
184
+ @click="continueToNext"
185
+ >
186
+ {{
187
+ currentStep === 0
188
+ ? fortalezasOption === 'automatico'
189
+ ? 'Finalizar'
190
+ : 'Siguiente'
191
+ : currentStep === totalSteps
192
+ ? 'Finalizar'
193
+ : 'Siguiente'
194
+ }}
195
+ </button>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ <!-- Modal de confirmación para regresar al paso 0 -->
202
+ <div v-if="showConfirmDialog" class="modal-overlay" @click.self="cancelGoBack">
203
+ <div class="modal-content confirm-dialog">
204
+ <div class="modal-header">
205
+ <div class="header-left">
206
+ <span class="modal-title">Confirmación</span>
207
+ </div>
208
+ </div>
209
+ <div class="header-separator"></div>
210
+ <div class="modal-body">
211
+ <div class="step-content">
212
+ <h3 class="confirm-dialog-title">¿Estás seguro de regresar?</h3>
213
+ <p class="confirm-dialog-message">Se perderá la información seleccionada</p>
214
+ </div>
215
+ </div>
216
+ <div class="modal-footer">
217
+ <div class="footer-actions">
218
+ <button class="cancel-btn" @click="cancelGoBack">Cancelar</button>
219
+ <button class="next-btn" @click="confirmGoBackToStep0">Confirmar</button>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </template>
225
+
226
+ <script setup>
227
+ import { ref, defineEmits, computed, nextTick } from 'vue'
228
+ import FortalezasView from './FortalezasView.vue'
229
+ import TirosEsquinaView from './TirosEsquinaView.vue'
230
+
231
+ const emit = defineEmits(['close', 'back', 'next'])
232
+
233
+ // Props para controlar el número de pasos
234
+ const props = defineProps({
235
+ hasRival: {
236
+ type: Boolean,
237
+ default: true,
238
+ },
239
+ token: {
240
+ type: String,
241
+ required: true,
242
+ },
243
+ template: {
244
+ type: Object,
245
+ required: false,
246
+ default: null,
247
+ },
248
+ team: {
249
+ type: Number,
250
+ required: false,
251
+ default: null,
252
+ },
253
+ partido: {
254
+ type: Object,
255
+ required: false,
256
+ default: null,
257
+ },
258
+ })
259
+
260
+ // Función para verificar si existe un componente Fortalezas en el template
261
+ function tieneComponenteFortalezas() {
262
+ if (!props.template || !props.template.pages) {
263
+ return false
264
+ }
265
+
266
+ // Iterar sobre todas las pages del template
267
+ for (const page of props.template.pages) {
268
+ // Verificar si la page tiene components
269
+ if (page.components && Array.isArray(page.components)) {
270
+ // Buscar si existe algún componente con name === 'Fortalezas' o id === 15
271
+ const tieneFortalezas = page.components.some(
272
+ (component) =>
273
+ component.title === 'Fortalezas' ||
274
+ component.id === 15 ||
275
+ component.componentName === 'GSCStrengths',
276
+ )
277
+ if (tieneFortalezas) {
278
+ return true
279
+ }
280
+ }
281
+ }
282
+
283
+ return false
284
+ }
285
+
286
+ // Función para contar Fortalezas del equipo propio y del rival
287
+ function contarFortalezas() {
288
+ console.log(
289
+ '5555555555555555 Nuevo Valor al crear fortalezas:: : : :: : : : :: : : :',
290
+ props.template,
291
+ )
292
+ if (!props.template || !props.template.pages) {
293
+ return { equipo: 0, rival: 0, total: 0 }
294
+ }
295
+ console.log('Nuevo Valor al crear fortalezas:: : : :: : : : :: : : :', props.template)
296
+
297
+ let countEquipo = 0
298
+ let countRival = 0
299
+
300
+ // Iterar sobre todas las pages del template
301
+ for (const page of props.template.pages) {
302
+ console.log('page 11 5555555555555555555555555555555555 ', page)
303
+ // Verificar si la page tiene components
304
+ if (page.components && Array.isArray(page.components)) {
305
+ console.log('page entro')
306
+ // Filtrar componentes Fortalezas
307
+ const componentesFortalezas = page.components.filter(
308
+ (component) =>
309
+ component.componentName === 'GSCStrengths' ||
310
+ component.id === 15 ||
311
+ component.name === 'Fortalezas',
312
+ )
313
+ console.log(
314
+ 'componentesFortalezas componentesFortalezas componentesFortalezas',
315
+ componentesFortalezas,
316
+ )
317
+ // Para cada componente Fortalezas, verificar dynamicFilters
318
+ for (const component of componentesFortalezas) {
319
+ // Verificar si tiene dynamicFilters y es un array
320
+ if (component.dynamicFilters && Array.isArray(component.dynamicFilters)) {
321
+ // Verificar la posición 1 (que es un array)
322
+ if (component.dynamicFilters[1]) {
323
+ // Consultar la posición 0 para determinar si es equipo propio (1) o rival (2)
324
+ if (component.dynamicFilters[0] === 1) {
325
+ countEquipo += component.dynamicFilters[1]
326
+ } else if (component.dynamicFilters[0] === 2) {
327
+ countRival += component.dynamicFilters[1]
328
+ } else {
329
+ if (component.dynamicFilters[0] === 3) {
330
+ if (component.filterMultiple.isHomeTeam) {
331
+ countEquipo += component.dynamicFilters[1]
332
+ } else {
333
+ countRival += component.dynamicFilters[1]
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+ console.log('CONTADOR FINAL DE FORTALEZAS: ', {
343
+ equipo: countEquipo,
344
+ rival: countRival,
345
+ total: countEquipo + countRival,
346
+ })
347
+ return {
348
+ equipo: countEquipo,
349
+ rival: countRival,
350
+ total: countEquipo + countRival,
351
+ }
352
+ }
353
+
354
+ // Computed para verificar si tiene Fortalezas
355
+ const hasFortalezas = computed(() => tieneComponenteFortalezas())
356
+
357
+ // Computed para obtener los conteos de Fortalezas
358
+ const fortalezasCounts = computed(() => contarFortalezas())
359
+
360
+ // Computed para determinar el texto del tipo de reporte
361
+ const tipoReporteTexto = computed(() => {
362
+ if (!props.template || !props.template.template_type) {
363
+ return 'Prepartido' // Valor por defecto
364
+ }
365
+ return props.template.template_type === 1 ? 'Prepartido' : 'Postpartido'
366
+ })
367
+
368
+ // const hasCorners = false // OCULTO POR EL MOMENTO
369
+ // Estado del modal
370
+ const currentStep = ref(0) // 0 = configuración inicial, luego pasos dinámicos
371
+ const isTransitioning = ref(false)
372
+
373
+ // Modal de confirmación para regresar al paso 0
374
+ const showConfirmDialog = ref(false)
375
+
376
+ // Opciones seleccionadas para cada sección
377
+ const fortalezasOption = ref('manual')
378
+ const tirosEsquinaOption = ref('manual')
379
+
380
+ // Selecciones por vista
381
+ const selectedFortalezasEquipo = ref([])
382
+ const selectedFortalezasRival = ref([])
383
+ const selectedCornersEquipo = ref([])
384
+ const selectedCornersRival = ref([])
385
+
386
+ // Calcular el número total de pasos
387
+ const totalSteps = computed(() => {
388
+ let steps = 0
389
+
390
+ // Pasos de Fortalezas
391
+ if (hasFortalezas.value && fortalezasOption.value === 'manual') {
392
+ // Si hay fortalezas de equipo, agregar paso 1
393
+ if (fortalezasCounts.value.equipo > 0) {
394
+ steps += 1
395
+ }
396
+ // Si hay fortalezas de rival, agregar paso (será 2 si hay equipo, 1 si no hay)
397
+ if (fortalezasCounts.value.rival > 0) {
398
+ steps += 1
399
+ }
400
+ }
401
+
402
+ // Pasos de Tiros de esquina - OCULTOS POR EL MOMENTO
403
+ // if (tirosEsquinaOption.value === 'manual') {
404
+ // steps += props.hasRival ? 2 : 1
405
+ // }
406
+
407
+ return Math.max(steps, 1)
408
+ })
409
+
410
+ // Verificar si se puede continuar al siguiente paso
411
+ const canContinue = computed(() => {
412
+ if (currentStep.value === 0) {
413
+ // Si no hay Fortalezas, no se puede continuar (tirosEsquina está oculto)
414
+ if (!hasFortalezas.value) {
415
+ return false
416
+ }
417
+ // Puede continuar si está en automático o en manual
418
+ return fortalezasOption.value === 'automatico' || fortalezasOption.value === 'manual'
419
+ }
420
+ const stepMap = buildStepMap()
421
+ const key = stepMap[currentStep.value]
422
+
423
+ if (key === 'fortalezasEquipo') {
424
+ const ref = fortalezasEquipoRef.value
425
+ if (!ref) return false
426
+ const selected = selectedFortalezasEquipo.value.length
427
+ const totalRequerido = fortalezasCounts.value.equipo
428
+ // Obtener el total de fortalezas disponibles del componente
429
+ const totalDisponibles = ref.fortalezasData?.length || 0
430
+
431
+ // Puede continuar si:
432
+ // 1. Selecciona el total exacto requerido
433
+ // 2. O si no hay suficientes disponibles, selecciona todos los disponibles
434
+ return (
435
+ selected === totalRequerido ||
436
+ (totalDisponibles > 0 && totalDisponibles < totalRequerido && selected === totalDisponibles)
437
+ )
438
+ }
439
+
440
+ if (key === 'fortalezasRival') {
441
+ const ref = fortalezasRivalRef.value
442
+ if (!ref) return false
443
+ const selected = selectedFortalezasRival.value.length
444
+ const totalRequerido = fortalezasCounts.value.rival
445
+ // Obtener el total de fortalezas disponibles del componente
446
+ const totalDisponibles = ref.fortalezasData?.length || 0
447
+
448
+ // Puede continuar si:
449
+ // 1. Selecciona el total exacto requerido
450
+ // 2. O si no hay suficientes disponibles, selecciona todos los disponibles
451
+ return (
452
+ selected === totalRequerido ||
453
+ (totalDisponibles > 0 && totalDisponibles < totalRequerido && selected === totalDisponibles)
454
+ )
455
+ }
456
+
457
+ // Pasos de corners ocultos
458
+ // if (key === 'cornersEquipo') return selectedCornersEquipo.value.length > 0
459
+ // if (key === 'cornersRival') return selectedCornersRival.value.length > 0
460
+ return false
461
+ })
462
+
463
+ function buildStepMap() {
464
+ const order = []
465
+
466
+ // Solo agregar pasos de Fortalezas si existen en el template y está en modo manual
467
+ if (hasFortalezas.value && fortalezasOption.value === 'manual') {
468
+ // Si hay fortalezas de equipo, agregar paso de equipo
469
+ if (fortalezasCounts.value.equipo > 0) {
470
+ order.push('fortalezasEquipo')
471
+ }
472
+ // Si hay fortalezas de rival, agregar paso de rival
473
+ if (fortalezasCounts.value.rival > 0) {
474
+ order.push('fortalezasRival')
475
+ }
476
+ }
477
+
478
+ // Pasos de Tiros de esquina - OCULTOS POR EL MOMENTO
479
+ // if (tirosEsquinaOption.value === 'manual') {
480
+ // order.push('cornersEquipo')
481
+ // if (props.hasRival) order.push('cornersRival')
482
+ // }
483
+
484
+ const map = {}
485
+ order.forEach((k, idx) => {
486
+ map[idx + 1] = k // pasos empiezan en 1
487
+ })
488
+ return map
489
+ }
490
+
491
+ // Referencias a los componentes
492
+ const fortalezasEquipoRef = ref(null)
493
+ const fortalezasRivalRef = ref(null)
494
+ const cornersEquipoRef = ref(null)
495
+ const cornersRivalRef = ref(null)
496
+
497
+ function closeModal() {
498
+ emit('close')
499
+ }
500
+
501
+ function goBack() {
502
+ if (currentStep.value > 1) {
503
+ // Si estamos en paso 2 o superior, solo regresar sin borrar selecciones
504
+ currentStep.value--
505
+ } else if (currentStep.value === 1) {
506
+ // Si estamos en paso 1 y vamos al paso 0, mostrar modal de confirmación
507
+ // Verificar si hay selecciones antes de mostrar el modal
508
+ const tieneSelecciones =
509
+ selectedFortalezasEquipo.value.length > 0 || selectedFortalezasRival.value.length > 0
510
+
511
+ if (tieneSelecciones) {
512
+ showConfirmDialog.value = true
513
+ } else {
514
+ // Si no hay selecciones, regresar directamente
515
+ currentStep.value--
516
+ }
517
+ } else {
518
+ // Si estamos en paso 0, emitir evento back
519
+ emit('back')
520
+ }
521
+ }
522
+
523
+ function confirmGoBackToStep0() {
524
+ // Limpiar todas las selecciones
525
+ selectedFortalezasEquipo.value = []
526
+ selectedFortalezasRival.value = []
527
+ selectedCornersEquipo.value = []
528
+ selectedCornersRival.value = []
529
+
530
+ // Cerrar el modal de confirmación
531
+ showConfirmDialog.value = false
532
+
533
+ // Regresar al paso 0
534
+ currentStep.value--
535
+ }
536
+
537
+ function cancelGoBack() {
538
+ // Cerrar el modal de confirmación sin hacer nada
539
+ showConfirmDialog.value = false
540
+ }
541
+
542
+ async function continueToNext() {
543
+ if (currentStep.value === 0) {
544
+ // Validar que al menos una opción esté seleccionada
545
+ if (!canContinue.value) {
546
+ return
547
+ }
548
+
549
+ // Si está en automático, finalizar directamente sin construir payload
550
+ if (fortalezasOption.value === 'automatico') {
551
+ // Emitir evento sin payload de strengths (se generarán automáticamente)
552
+ emit('next', {
553
+ fortalezas: fortalezasOption.value,
554
+ tirosEsquina: tirosEsquinaOption.value,
555
+ selectedFortalezasEquipo: [],
556
+ selectedFortalezasRival: [],
557
+ strengthsPayload: {}, // Payload vacío para modo automático
558
+ })
559
+ return
560
+ }
561
+
562
+ // Si es manual, avanzar al siguiente paso
563
+ // Animar transición
564
+ isTransitioning.value = true
565
+ setTimeout(() => {
566
+ currentStep.value++
567
+ isTransitioning.value = false
568
+ }, 300)
569
+ } else if (currentStep.value < totalSteps.value) {
570
+ // Avanzar al siguiente paso
571
+ isTransitioning.value = true
572
+ setTimeout(() => {
573
+ currentStep.value++
574
+ isTransitioning.value = false
575
+ }, 300)
576
+ } else {
577
+ // Esperar un tick para asegurar que los refs estén disponibles
578
+ await nextTick()
579
+
580
+ // Construir el payload de fortalezas antes de emitir
581
+ const strengthsPayload = buildStrengthsPayload()
582
+ console.log('Estructura de strengths emitida:', JSON.stringify(strengthsPayload, null, 2))
583
+
584
+ // Emitir evento con las opciones seleccionadas y el payload de fortalezas
585
+ emit('next', {
586
+ fortalezas: fortalezasOption.value,
587
+ tirosEsquina: tirosEsquinaOption.value,
588
+ selectedFortalezasEquipo: selectedFortalezasEquipo.value,
589
+ selectedFortalezasRival: selectedFortalezasRival.value,
590
+ strengthsPayload,
591
+ })
592
+ }
593
+ }
594
+
595
+ // Función para construir el payload de fortalezas según la estructura requerida
596
+ function buildStrengthsPayload() {
597
+ console.log('=== INICIANDO buildStrengthsPayload ===')
598
+ console.log('Template:', props.template)
599
+ console.log('Template pages:', props.template?.pages)
600
+
601
+ if (!props.template || !props.template.pages) {
602
+ console.warn('No hay template o pages')
603
+ return {}
604
+ }
605
+
606
+ const payload = {}
607
+
608
+ console.log('selectedFortalezasEquipo:', selectedFortalezasEquipo.value)
609
+ console.log('selectedFortalezasRival:', selectedFortalezasRival.value)
610
+ console.log('fortalezasEquipoRef:', fortalezasEquipoRef.value)
611
+ console.log('fortalezasRivalRef:', fortalezasRivalRef.value)
612
+
613
+ // Verificar si los refs están disponibles
614
+ let equipoRef = fortalezasEquipoRef.value
615
+ let rivalRef = fortalezasRivalRef.value
616
+
617
+ // Debug detallado de los refs
618
+ if (equipoRef) {
619
+ console.log('equipoRef keys:', Object.keys(equipoRef))
620
+ console.log('equipoRef.fortalezasRawData:', equipoRef.fortalezasRawData)
621
+ console.log('equipoRef.fortalezasRawData type:', typeof equipoRef.fortalezasRawData)
622
+
623
+ // Verificar si es un ref (tiene .value)
624
+ let rawDataEquipo = equipoRef.fortalezasRawData
625
+ if (rawDataEquipo && typeof rawDataEquipo === 'object' && 'value' in rawDataEquipo) {
626
+ console.log('⚠️ fortalezasRawData es un ref, usando .value')
627
+ rawDataEquipo = rawDataEquipo.value
628
+ }
629
+
630
+ console.log('rawDataEquipo después de verificar ref:', rawDataEquipo)
631
+ console.log('rawDataEquipo is array:', Array.isArray(rawDataEquipo))
632
+ if (Array.isArray(rawDataEquipo)) {
633
+ console.log('rawDataEquipo length:', rawDataEquipo.length)
634
+ if (rawDataEquipo.length > 0) {
635
+ console.log('Primer elemento equipoRef:', rawDataEquipo[0])
636
+ }
637
+ }
638
+ } else {
639
+ console.error('❌ equipoRef NO está disponible')
640
+ }
641
+
642
+ if (rivalRef) {
643
+ console.log('rivalRef keys:', Object.keys(rivalRef))
644
+ console.log('rivalRef.fortalezasRawData:', rivalRef.fortalezasRawData)
645
+ console.log('rivalRef.fortalezasRawData type:', typeof rivalRef.fortalezasRawData)
646
+
647
+ // Verificar si es un ref (tiene .value)
648
+ let rawDataRival = rivalRef.fortalezasRawData
649
+ if (rawDataRival && typeof rawDataRival === 'object' && 'value' in rawDataRival) {
650
+ console.log('⚠️ fortalezasRawData es un ref, usando .value')
651
+ rawDataRival = rawDataRival.value
652
+ }
653
+
654
+ console.log('rawDataRival después de verificar ref:', rawDataRival)
655
+ console.log('rawDataRival is array:', Array.isArray(rawDataRival))
656
+ if (Array.isArray(rawDataRival)) {
657
+ console.log('rawDataRival length:', rawDataRival.length)
658
+ if (rawDataRival.length > 0) {
659
+ console.log('Primer elemento rivalRef:', rawDataRival[0])
660
+ }
661
+ }
662
+ } else {
663
+ console.error('❌ rivalRef NO está disponible')
664
+ }
665
+
666
+ // Si los refs no están disponibles, podría ser que los componentes estén ocultos con v-show
667
+ if (!equipoRef && selectedFortalezasEquipo.value.length > 0) {
668
+ console.warn('⚠️ Ref de equipo no disponible, pero hay selecciones')
669
+ }
670
+ if (!rivalRef && selectedFortalezasRival.value.length > 0) {
671
+ console.warn('⚠️ Ref de rival no disponible, pero hay selecciones')
672
+ }
673
+
674
+ // Obtener todas las fortalezas seleccionadas ordenadas por su orden de selección
675
+ const fortalezasEquipoOrdenadas = getOrderedStrengths(selectedFortalezasEquipo.value, equipoRef)
676
+ const fortalezasRivalOrdenadas = getOrderedStrengths(selectedFortalezasRival.value, rivalRef)
677
+
678
+ console.log('fortalezasEquipoOrdenadas:', fortalezasEquipoOrdenadas)
679
+ console.log('fortalezasRivalOrdenadas:', fortalezasRivalOrdenadas)
680
+
681
+ // Contadores para rastrear qué fortalezas ya se han asignado
682
+ let indexEquipo = 0
683
+ let indexRival = 0
684
+
685
+ // Iterar sobre todas las páginas del template
686
+ props.template.pages.forEach((page, pageIndex) => {
687
+ const pageNumber = pageIndex + 1 // Los índices de página empiezan en 1
688
+ console.log(`\n=== Página ${pageNumber} ===`)
689
+ console.log('Page components:', page.components)
690
+
691
+ // Verificar si la página tiene components
692
+ if (page.components && Array.isArray(page.components)) {
693
+ // Buscar componentes Fortalezas - usar la misma condición que en contarFortalezas
694
+ page.components.forEach((component, componentIndex) => {
695
+ const esComponenteFortalezas =
696
+ component.componentName === 'GSCStrengths' ||
697
+ component.id === 15 ||
698
+ component.name === 'Fortalezas' ||
699
+ component.title === 'Fortalezas'
700
+
701
+ if (esComponenteFortalezas) {
702
+ const componentNumber = componentIndex + 1 // Los índices de componente empiezan en 1
703
+ console.log(
704
+ `\n--- Componente ${componentNumber} (Fortalezas) en página ${pageNumber} ---`,
705
+ )
706
+ console.log('Component:', component)
707
+ console.log('Component properties:', {
708
+ name: component.name,
709
+ title: component.title,
710
+ componentName: component.componentName,
711
+ id: component.id,
712
+ })
713
+ console.log('dynamicFilters:', component.dynamicFilters)
714
+
715
+ // Verificar dynamicFilters para determinar tipo y cantidad
716
+ if (component.dynamicFilters && Array.isArray(component.dynamicFilters)) {
717
+ const teamType = component.dynamicFilters[0] // 1 = equipo, 2 = rival, 3 = dinámico
718
+ const cantidadRequerida = component.dynamicFilters[1] || 0 // Cantidad de fortalezas necesarias
719
+
720
+ console.log(
721
+ `Tipo: ${teamType === 1 ? 'Equipo' : teamType === 2 ? 'Rival' : 'Dinámico (3)'}, Cantidad requerida: ${cantidadRequerida}`,
722
+ )
723
+
724
+ // Obtener las fortalezas según el tipo
725
+ let fortalezasAsignar = []
726
+ let fortalezasOrdenadas = []
727
+ let teamId = props.team
728
+
729
+ if (teamType === 1) {
730
+ // Fortalezas de equipo
731
+ fortalezasOrdenadas = fortalezasEquipoOrdenadas
732
+ console.log(
733
+ `Equipo: Total ordenadas=${fortalezasOrdenadas.length}, index=${indexEquipo}, cantidad requerida=${cantidadRequerida}`,
734
+ )
735
+ // Tomar las siguientes N fortalezas (donde N = cantidadRequerida)
736
+ if (fortalezasOrdenadas.length > indexEquipo) {
737
+ fortalezasAsignar = fortalezasOrdenadas.slice(
738
+ indexEquipo,
739
+ indexEquipo + cantidadRequerida,
740
+ )
741
+ console.log(
742
+ `Index equipo: ${indexEquipo}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
743
+ )
744
+ } else {
745
+ console.warn(
746
+ `No hay suficientes fortalezas de equipo. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexEquipo}`,
747
+ )
748
+ }
749
+ indexEquipo += cantidadRequerida
750
+ teamId = props.partido?.local || props.partido?.home_team || props.team
751
+ } else if (teamType === 2) {
752
+ // Fortalezas de rival
753
+ fortalezasOrdenadas = fortalezasRivalOrdenadas
754
+ console.log(
755
+ `Rival: Total ordenadas=${fortalezasOrdenadas.length}, index=${indexRival}, cantidad requerida=${cantidadRequerida}`,
756
+ )
757
+ // Tomar las siguientes N fortalezas (donde N = cantidadRequerida)
758
+ if (fortalezasOrdenadas.length > indexRival) {
759
+ fortalezasAsignar = fortalezasOrdenadas.slice(
760
+ indexRival,
761
+ indexRival + cantidadRequerida,
762
+ )
763
+ console.log(
764
+ `Index rival: ${indexRival}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
765
+ )
766
+ } else {
767
+ console.warn(
768
+ `No hay suficientes fortalezas de rival. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexRival}`,
769
+ )
770
+ }
771
+ indexRival += cantidadRequerida
772
+ teamId = props.partido?.visita || props.partido?.visiting_team
773
+ } else if (teamType === 3) {
774
+ // Tipo dinámico: depende de filterMultiple.isHomeTeam
775
+ if (component.filterMultiple && component.filterMultiple.isHomeTeam) {
776
+ // Es equipo
777
+ fortalezasOrdenadas = fortalezasEquipoOrdenadas
778
+ console.log(
779
+ `Dinámico (Equipo): Total ordenadas=${fortalezasOrdenadas.length}, index=${indexEquipo}, cantidad requerida=${cantidadRequerida}`,
780
+ )
781
+ if (fortalezasOrdenadas.length > indexEquipo) {
782
+ fortalezasAsignar = fortalezasOrdenadas.slice(
783
+ indexEquipo,
784
+ indexEquipo + cantidadRequerida,
785
+ )
786
+ console.log(
787
+ `Index equipo: ${indexEquipo}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
788
+ )
789
+ } else {
790
+ console.warn(
791
+ `No hay suficientes fortalezas de equipo. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexEquipo}`,
792
+ )
793
+ }
794
+ indexEquipo += cantidadRequerida
795
+ teamId = props.partido?.local || props.partido?.home_team || props.team
796
+ } else {
797
+ // Es rival
798
+ fortalezasOrdenadas = fortalezasRivalOrdenadas
799
+ console.log(
800
+ `Dinámico (Rival): Total ordenadas=${fortalezasOrdenadas.length}, index=${indexRival}, cantidad requerida=${cantidadRequerida}`,
801
+ )
802
+ if (fortalezasOrdenadas.length > indexRival) {
803
+ fortalezasAsignar = fortalezasOrdenadas.slice(
804
+ indexRival,
805
+ indexRival + cantidadRequerida,
806
+ )
807
+ console.log(
808
+ `Index rival: ${indexRival}, tomando ${fortalezasAsignar.length} fortalezas de ${fortalezasOrdenadas.length} disponibles`,
809
+ )
810
+ } else {
811
+ console.warn(
812
+ `No hay suficientes fortalezas de rival. Disponibles: ${fortalezasOrdenadas.length}, Necesarias desde índice: ${indexRival}`,
813
+ )
814
+ }
815
+ indexRival += cantidadRequerida
816
+ teamId = props.partido?.visita || props.partido?.visiting_team
817
+ }
818
+ }
819
+
820
+ console.log('fortalezasAsignar:', fortalezasAsignar)
821
+
822
+ // Si hay fortalezas para asignar, agregarlas al payload
823
+ if (fortalezasAsignar.length > 0) {
824
+ // Inicializar la estructura si no existe
825
+ if (!payload[pageNumber]) {
826
+ payload[pageNumber] = {}
827
+ }
828
+ if (!payload[pageNumber][componentNumber]) {
829
+ payload[pageNumber][componentNumber] = []
830
+ }
831
+
832
+ // Agregar las fortalezas con su información completa
833
+ fortalezasAsignar.forEach((strength, index) => {
834
+ payload[pageNumber][componentNumber].push({
835
+ team_id: teamId,
836
+ ranking_type: strength.ranking_type || 1,
837
+ precondition_id: strength.precondition_id || null,
838
+ order: index + 1,
839
+ name: strength.name,
840
+ category_type: strength.category_type || 1,
841
+ total: strength.total || 0,
842
+ is_relevant: strength.is_relevant || 0,
843
+ league_ranking: strength.league_ranking || 0,
844
+ categories: Array.isArray(strength.categories)
845
+ ? strength.categories
846
+ : [strength.categories],
847
+ team_contribution: strength.team_contribution || 0,
848
+ })
849
+ })
850
+ console.log(
851
+ `✓ Agregadas ${fortalezasAsignar.length} fortalezas al payload para componente ${componentNumber} en página ${pageNumber}`,
852
+ )
853
+ console.log(
854
+ `Payload actual para página ${pageNumber}:`,
855
+ JSON.stringify(payload[pageNumber], null, 2),
856
+ )
857
+ } else {
858
+ console.warn(
859
+ `⚠️ No hay fortalezas para asignar al componente ${componentNumber} en página ${pageNumber}. IndexEquipo: ${indexEquipo}, IndexRival: ${indexRival}`,
860
+ )
861
+ }
862
+ } else {
863
+ console.warn(
864
+ `⚠️ Componente ${componentIndex + 1} en página ${pageNumber} no tiene dynamicFilters válido`,
865
+ )
866
+ console.warn('Component:', component)
867
+ }
868
+ }
869
+ })
870
+ console.log(
871
+ `\n✓ Página ${pageNumber} procesada. Componentes de Fortalezas encontrados y procesados.`,
872
+ )
873
+ }
874
+ })
875
+
876
+ console.log('\n=== PAYLOAD FINAL ===')
877
+ console.log(JSON.stringify(payload, null, 2))
878
+ return payload
879
+ }
880
+
881
+ // Función auxiliar para obtener las fortalezas en el mismo orden que fueron seleccionadas
882
+ // Los IDs ya vienen en el orden correcto, solo necesitamos obtener los objetos completos
883
+ function getOrderedStrengths(selectedIds, fortalezasViewRef) {
884
+ console.log('=== getOrderedStrengths INICIO ===')
885
+ console.log('selectedIds (orden de selección):', selectedIds)
886
+ console.log('fortalezasViewRef existe?:', !!fortalezasViewRef)
887
+
888
+ if (!selectedIds || selectedIds.length === 0) {
889
+ console.warn('No hay IDs seleccionados')
890
+ return []
891
+ }
892
+
893
+ if (!fortalezasViewRef) {
894
+ console.warn('Ref no disponible')
895
+ return []
896
+ }
897
+
898
+ // Obtener fortalezasRawData, verificando si es un ref
899
+ let fortalezasRawData = fortalezasViewRef.fortalezasRawData
900
+ if (!fortalezasRawData) {
901
+ console.warn('fortalezasRawData no está disponible en el ref')
902
+ return []
903
+ }
904
+
905
+ // Si es un ref, acceder a su .value
906
+ if (fortalezasRawData && typeof fortalezasRawData === 'object' && 'value' in fortalezasRawData) {
907
+ console.log('⚠️ fortalezasRawData es un ref, accediendo a .value')
908
+ fortalezasRawData = fortalezasRawData.value
909
+ }
910
+
911
+ if (!Array.isArray(fortalezasRawData)) {
912
+ console.warn('fortalezasRawData no es un array:', typeof fortalezasRawData, fortalezasRawData)
913
+ return []
914
+ }
915
+
916
+ if (fortalezasRawData.length === 0) {
917
+ console.warn('fortalezasRawData está vacío')
918
+ return []
919
+ }
920
+
921
+ console.log('fortalezasRawData length:', fortalezasRawData.length)
922
+ console.log('Primeras 2 fortalezas raw:', fortalezasRawData.slice(0, 2))
923
+
924
+ // Obtener las fortalezas en el mismo orden que fueron seleccionadas (sin reordenar)
925
+ // El orden ya está dado por selectedIds, solo necesitamos buscar y devolver el objeto completo
926
+ const selectedStrengths = selectedIds
927
+ .map((id) => {
928
+ console.log(`Buscando ID: ${id} (tipo: ${typeof id})`)
929
+
930
+ // Buscar en los datos raw por categories (que es el id que usamos)
931
+ const strength = fortalezasRawData.find((item) => {
932
+ // Comparar tanto como número como string
933
+ const match =
934
+ item.categories === id ||
935
+ item.categories === Number(id) ||
936
+ String(item.categories) === String(id)
937
+ if (!match && fortalezasRawData.indexOf(item) < 3) {
938
+ console.log(
939
+ ` Comparando: item.categories=${item.categories} (${typeof item.categories}) vs id=${id} (${typeof id})`,
940
+ )
941
+ }
942
+ return match
943
+ })
944
+
945
+ if (strength) {
946
+ console.log(`✓ Encontrada: ${strength.name} (categories: ${strength.categories})`)
947
+ return strength
948
+ }
949
+
950
+ console.warn(`✗ No encontrada con categories = ${id}, intentando por id`)
951
+ // Intentar buscar también por id si categories no funciona
952
+ const strengthById = fortalezasRawData.find(
953
+ (item) => item.id === id || item.id === Number(id) || String(item.id) === String(id),
954
+ )
955
+ if (strengthById) {
956
+ console.log(`✓ Encontrada por id: ${strengthById.name}`)
957
+ return strengthById
958
+ }
959
+
960
+ console.error(`✗✗ No se encontró fortaleza con id/categories = ${id}`)
961
+ return null
962
+ })
963
+ .filter(Boolean) // Filtrar los que no se encontraron
964
+
965
+ console.log(
966
+ `selectedStrengths (${selectedStrengths.length} de ${selectedIds.length} encontradas):`,
967
+ selectedStrengths,
968
+ )
969
+ console.log('=== getOrderedStrengths FIN ===')
970
+ return selectedStrengths
971
+ }
972
+
973
+ function autocompletar() {
974
+ const stepMap = buildStepMap()
975
+ const key = stepMap[currentStep.value]
976
+ if (key === 'fortalezasEquipo' && fortalezasEquipoRef.value)
977
+ return fortalezasEquipoRef.value.autocompletar()
978
+ if (key === 'fortalezasRival' && fortalezasRivalRef.value)
979
+ return fortalezasRivalRef.value.autocompletar()
980
+ if (key === 'cornersEquipo' && cornersEquipoRef.value)
981
+ return cornersEquipoRef.value.autocompletar()
982
+ if (key === 'cornersRival' && cornersRivalRef.value) return cornersRivalRef.value.autocompletar()
983
+ }
984
+ </script>
985
+
986
+ <style scoped>
987
+ .modal-overlay {
988
+ position: fixed;
989
+ top: 0;
990
+ left: 0;
991
+ width: 100vw;
992
+ height: 100vh;
993
+ background: rgba(0, 0, 0, 0.45);
994
+ display: flex;
995
+ align-items: center;
996
+ justify-content: center;
997
+ z-index: 3300;
998
+ }
999
+
1000
+ .modal-content {
1001
+ width: 464px;
1002
+ background: #2e3b46;
1003
+ border-radius: 10px;
1004
+ box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.18);
1005
+ padding: 0;
1006
+ position: relative;
1007
+ display: flex;
1008
+ flex-direction: column;
1009
+ font-family: 'Poppins-Medium', 'Montserrat', sans-serif;
1010
+ }
1011
+
1012
+ /* Estilos del botón de cerrar removidos */
1013
+
1014
+ .header-separator {
1015
+ width: 100%;
1016
+ height: 1px;
1017
+ border-bottom: dashed 1px #58626b;
1018
+ margin: 12px 0 0 0;
1019
+ }
1020
+
1021
+ .modal-header {
1022
+ display: flex;
1023
+ align-items: center;
1024
+ justify-content: space-between;
1025
+ padding: 20px 24px 0 24px;
1026
+ }
1027
+
1028
+ .header-left {
1029
+ display: flex;
1030
+ align-items: center;
1031
+ gap: 8px;
1032
+ }
1033
+
1034
+ .step-counter {
1035
+ font-family: Poppins-Medium;
1036
+ font-size: 12px;
1037
+ font-weight: 500;
1038
+ color: rgba(255, 255, 255, 0.7);
1039
+ }
1040
+
1041
+ .icon-title {
1042
+ width: 16px;
1043
+ height: 16px;
1044
+ }
1045
+
1046
+ .modal-title {
1047
+ font-family: Poppins-Medium;
1048
+ font-size: 14px;
1049
+ font-weight: 500;
1050
+ font-stretch: normal;
1051
+ font-style: normal;
1052
+ line-height: 1.5;
1053
+ letter-spacing: normal;
1054
+ text-align: left;
1055
+ color: #fff;
1056
+ }
1057
+
1058
+ .prepartido-text {
1059
+ font-family: 'Poppins-Regular', 'BebasNeue', sans-serif;
1060
+ font-weight: 400;
1061
+ opacity: 0.7;
1062
+ letter-spacing: 1px;
1063
+ }
1064
+
1065
+ .modal-body {
1066
+ flex: 1;
1067
+ display: flex;
1068
+ flex-direction: column;
1069
+ padding: 12px 24px 0 24px;
1070
+ margin-bottom: 17px;
1071
+ margin-top: 5px;
1072
+ gap: 0;
1073
+ position: relative;
1074
+ overflow: hidden;
1075
+ }
1076
+
1077
+ .step-content {
1078
+ transition: transform 0.3s ease-in-out;
1079
+ }
1080
+
1081
+ .modal-body.transitioning .step-content {
1082
+ transform: translateX(-100%);
1083
+ }
1084
+
1085
+ .fortalezas-view {
1086
+ transform: translateX(100%);
1087
+ animation: slideIn 0.3s ease-in-out forwards;
1088
+ }
1089
+
1090
+ @keyframes slideIn {
1091
+ from {
1092
+ transform: translateX(100%);
1093
+ }
1094
+ to {
1095
+ transform: translateX(0);
1096
+ }
1097
+ }
1098
+
1099
+ .content-section {
1100
+ background: none;
1101
+ border: solid 1px rgba(255, 255, 255, 0.4);
1102
+ padding: 12px 20px 20px 20px;
1103
+ margin-bottom: 0;
1104
+ border-radius: 8px;
1105
+ }
1106
+
1107
+ .content-section:first-child {
1108
+ margin-bottom: 20px;
1109
+ }
1110
+
1111
+ .title-separator {
1112
+ width: 100%;
1113
+ height: 1px;
1114
+ border-top: 1px dashed rgba(255, 255, 255, 0.3);
1115
+ margin: 8px 0 12px 0;
1116
+ margin-left: -20px;
1117
+ margin-right: -20px;
1118
+ width: calc(100% + 40px);
1119
+ }
1120
+
1121
+ .content-separator {
1122
+ width: 100%;
1123
+ height: 1px;
1124
+ border-top: 1px dashed rgba(255, 255, 255, 0.3);
1125
+ margin: 12px 0 16px 0;
1126
+ margin-left: -20px;
1127
+ margin-right: -20px;
1128
+ width: calc(100% + 40px);
1129
+ }
1130
+
1131
+ .section-title {
1132
+ font-family: Poppins-Medium;
1133
+ font-size: 14px;
1134
+ font-weight: 600;
1135
+ opacity: 0.9;
1136
+ color: #fff;
1137
+ margin: 0 0 12px 0;
1138
+ }
1139
+
1140
+ .section-description {
1141
+ font-family: Poppins-Regular;
1142
+ font-size: 12px;
1143
+ line-height: 1.4;
1144
+ opacity: 0.7;
1145
+ color: #fff;
1146
+ margin: 0 0 13px 0;
1147
+ }
1148
+
1149
+ .radio-group {
1150
+ display: flex;
1151
+ gap: 24px;
1152
+ justify-content: center;
1153
+ }
1154
+
1155
+ .radio-option {
1156
+ display: flex;
1157
+ align-items: center;
1158
+ gap: 8px;
1159
+ cursor: pointer;
1160
+ user-select: none;
1161
+ }
1162
+
1163
+ .radio-option input[type='radio'] {
1164
+ display: none;
1165
+ }
1166
+
1167
+ .radio-custom {
1168
+ width: 20px;
1169
+ height: 20px;
1170
+ border: 1px solid #fff;
1171
+ border-radius: 50%;
1172
+ position: relative;
1173
+ transition: all 0.2s ease;
1174
+ flex-shrink: 0;
1175
+ }
1176
+
1177
+ .radio-option input[type='radio']:checked + .radio-custom {
1178
+ border-color: #fff; /* mantiene el aro blanco */
1179
+ background-color: transparent; /* sin relleno, solo punto central */
1180
+ }
1181
+
1182
+ .radio-option input[type='radio']:checked + .radio-custom::after {
1183
+ content: '';
1184
+ position: absolute;
1185
+ top: 50%;
1186
+ left: 50%;
1187
+ transform: translate(-50%, -50%);
1188
+ width: 10px;
1189
+ height: 10px;
1190
+ background-color: #cbee6b; /* punto verde */
1191
+ border-radius: 50%;
1192
+ }
1193
+
1194
+ /* Cuando el radio está seleccionado, la etiqueta pierde la opacidad */
1195
+ .radio-option input[type='radio']:checked + .radio-custom + .radio-label {
1196
+ opacity: 0.9;
1197
+ }
1198
+
1199
+ .radio-label {
1200
+ font-family: Poppins-Regular;
1201
+ font-size: 13px;
1202
+ color: #fff;
1203
+ opacity: 0.7;
1204
+ }
1205
+
1206
+ /* Estilos del separador removidos */
1207
+
1208
+ .modal-footer {
1209
+ display: flex;
1210
+ justify-content: space-between;
1211
+ align-items: center;
1212
+ padding: 0 24px 12px 24px;
1213
+ margin-top: 13px;
1214
+ }
1215
+
1216
+ .footer-actions {
1217
+ display: flex;
1218
+ align-items: center;
1219
+ }
1220
+
1221
+ .back-btn {
1222
+ background: none;
1223
+ border: none;
1224
+ color: #fff;
1225
+ font-size: 14px;
1226
+ font-family: Poppins-Medium;
1227
+ display: flex;
1228
+ align-items: center;
1229
+ gap: 4px;
1230
+ cursor: pointer;
1231
+ opacity: 0.7;
1232
+ padding: 8px 0;
1233
+ transition: opacity 0.2s;
1234
+ }
1235
+
1236
+ .back-btn:hover {
1237
+ opacity: 1;
1238
+ }
1239
+
1240
+ .cancel-btn {
1241
+ background: none;
1242
+ border: none;
1243
+ color: #b0bec5;
1244
+ font-size: 14.9px;
1245
+ font-family: Poppins-Medium;
1246
+ height: 30px;
1247
+ border-radius: 64px;
1248
+ display: flex;
1249
+ align-items: center;
1250
+ justify-content: center;
1251
+ cursor: pointer;
1252
+ padding: 0 18px;
1253
+ transition: color 0.2s;
1254
+ text-decoration: underline;
1255
+ }
1256
+
1257
+ .cancel-btn:hover {
1258
+ color: #fff;
1259
+ }
1260
+
1261
+ .next-btn {
1262
+ width: 107px;
1263
+ height: 30px;
1264
+ border-radius: 79.2px;
1265
+ -webkit-backdrop-filter: blur(19.8px);
1266
+ backdrop-filter: blur(19.8px);
1267
+ border: solid 1px #cbee6b;
1268
+ background-color: rgba(255, 255, 255, 0.06);
1269
+ font-family: Poppins-Medium;
1270
+ font-size: 14.9px;
1271
+ font-weight: 500;
1272
+ color: #fff;
1273
+ cursor: pointer;
1274
+ transition: background 0.2s;
1275
+ display: flex;
1276
+ align-items: center;
1277
+ justify-content: center;
1278
+ }
1279
+
1280
+ .next-btn:hover {
1281
+ background-color: rgba(255, 255, 255, 0.12);
1282
+ }
1283
+
1284
+ .next-btn.disabled {
1285
+ opacity: 0.5;
1286
+ cursor: not-allowed;
1287
+ }
1288
+
1289
+ .next-btn.disabled:hover {
1290
+ background-color: rgba(255, 255, 255, 0.06);
1291
+ }
1292
+
1293
+ /* Estilos para el modal de confirmación */
1294
+ .confirm-dialog {
1295
+ width: 380px;
1296
+ max-width: 90%;
1297
+ }
1298
+
1299
+ /* Asegurar que el overlay del modal de confirmación esté por encima del modal principal */
1300
+ .modal-overlay:has(.confirm-dialog) {
1301
+ z-index: 3400;
1302
+ }
1303
+
1304
+ .confirm-dialog .modal-header {
1305
+ justify-content: center;
1306
+ }
1307
+
1308
+ .confirm-dialog .modal-body {
1309
+ text-align: center;
1310
+ }
1311
+
1312
+ .confirm-dialog-title {
1313
+ font-family: Poppins-Medium;
1314
+ font-size: 16px;
1315
+ font-weight: 500;
1316
+ color: #fff;
1317
+ margin: 0 0 12px 0;
1318
+ text-align: center;
1319
+ }
1320
+
1321
+ .confirm-dialog-message {
1322
+ font-family: Poppins-Regular;
1323
+ font-size: 14px;
1324
+ color: rgba(255, 255, 255, 0.7);
1325
+ margin: 0;
1326
+ text-align: center;
1327
+ line-height: 1.5;
1328
+ }
1329
+
1330
+ .confirm-dialog .modal-footer {
1331
+ justify-content: center;
1332
+ }
1333
+
1334
+ .confirm-dialog .footer-actions {
1335
+ width: 100%;
1336
+ justify-content: center;
1337
+ gap: 12px;
1338
+ }
1339
+
1340
+ /* Estilos para la vista de fortalezas movidos al componente FortalezasView.vue */
1341
+ </style>