@golstats/gsc-reports 1.0.0
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.
- package/README.md +2 -0
- package/dist/FilterConditions-55d68355-C5NIJbY6-xW04mYhu-DRN4eEO4.js +191 -0
- package/dist/FilterField-59a73e38-DO8nYLqs-Da7H_Fvj-ZuLwDGOM.js +21 -0
- package/dist/FilterSubcategories-a9b32cc9-DlkHni1L-BXid_sIn-BvoU3OqZ.js +42 -0
- package/dist/css/fonts.css +83 -0
- package/dist/fonts/BebasNeue-Bold.otf +0 -0
- package/dist/fonts/BebasNeue-Bold.ttf +0 -0
- package/dist/fonts/BebasNeue-Bold.woff2 +0 -0
- package/dist/fonts/BebasNeue-Book.otf +0 -0
- package/dist/fonts/BebasNeue-Book.ttf +0 -0
- package/dist/fonts/BebasNeue-Book.woff2 +0 -0
- package/dist/fonts/BebasNeue-Light.otf +0 -0
- package/dist/fonts/BebasNeue-Light.ttf +0 -0
- package/dist/fonts/BebasNeue-Light.woff2 +0 -0
- package/dist/fonts/BebasNeue-Regular.otf +0 -0
- package/dist/fonts/BebasNeue-Regular.ttf +0 -0
- package/dist/fonts/BebasNeue-Regular.woff2 +0 -0
- package/dist/fonts/BebasNeue-Thin.otf +0 -0
- package/dist/fonts/BebasNeue-Thin.ttf +0 -0
- package/dist/fonts/BebasNeue-Thin.woff2 +0 -0
- package/dist/fonts/Montserrat-Black.otf +0 -0
- package/dist/fonts/Montserrat-BlackItalic.otf +0 -0
- package/dist/fonts/Montserrat-Bold.otf +0 -0
- package/dist/fonts/Montserrat-BoldItalic.otf +0 -0
- package/dist/fonts/Montserrat-ExtraBold.otf +0 -0
- package/dist/fonts/Montserrat-ExtraBoldItalic.otf +0 -0
- package/dist/fonts/Montserrat-ExtraLight.otf +0 -0
- package/dist/fonts/Montserrat-ExtraLightItalic.otf +0 -0
- package/dist/fonts/Montserrat-Italic.otf +0 -0
- package/dist/fonts/Montserrat-Light.otf +0 -0
- package/dist/fonts/Montserrat-LightItalic.otf +0 -0
- package/dist/fonts/Montserrat-Medium.otf +0 -0
- package/dist/fonts/Montserrat-MediumItalic.otf +0 -0
- package/dist/fonts/Montserrat-Regular.otf +0 -0
- package/dist/fonts/Montserrat-SemiBold.otf +0 -0
- package/dist/fonts/Montserrat-SemiBoldItalic.otf +0 -0
- package/dist/fonts/Montserrat-Thin.otf +0 -0
- package/dist/fonts/Montserrat-ThinItalic.otf +0 -0
- package/dist/fonts/Oswald-Bold.ttf +0 -0
- package/dist/fonts/Oswald-ExtraLight.ttf +0 -0
- package/dist/fonts/Oswald-Light.ttf +0 -0
- package/dist/fonts/Oswald-Medium.ttf +0 -0
- package/dist/fonts/Oswald-Regular.ttf +0 -0
- package/dist/fonts/Oswald-SemiBold.ttf +0 -0
- package/dist/fonts/Poppins-Black.otf +0 -0
- package/dist/fonts/Poppins-BlackItalic.otf +0 -0
- package/dist/fonts/Poppins-Bold.otf +0 -0
- package/dist/fonts/Poppins-BoldItalic.otf +0 -0
- package/dist/fonts/Poppins-ExtraBold.otf +0 -0
- package/dist/fonts/Poppins-ExtraBoldItalic.otf +0 -0
- package/dist/fonts/Poppins-ExtraLight.otf +0 -0
- package/dist/fonts/Poppins-ExtraLightItalic.otf +0 -0
- package/dist/fonts/Poppins-Italic.otf +0 -0
- package/dist/fonts/Poppins-Light.otf +0 -0
- package/dist/fonts/Poppins-LightItalic.otf +0 -0
- package/dist/fonts/Poppins-Medium.otf +0 -0
- package/dist/fonts/Poppins-MediumItalic.otf +0 -0
- package/dist/fonts/Poppins-Regular.otf +0 -0
- package/dist/fonts/Poppins-SemiBold.otf +0 -0
- package/dist/fonts/Poppins-SemiBoldItalic.otf +0 -0
- package/dist/fonts/Poppins-Thin.otf +0 -0
- package/dist/fonts/Poppins-ThinItalic.otf +0 -0
- package/dist/gsc-reports.css +1 -0
- package/dist/gsc-reports.es.js +4 -0
- package/dist/gsc-reports.umd.js +4079 -0
- package/dist/icons/icn-close.svg +5 -0
- package/dist/icons/icn-delete-delete.svg +3 -0
- package/dist/icons/icn-delete.svg +3 -0
- package/dist/icons/icn-download.svg +4 -0
- package/dist/icons/icn-duplicate-white.svg +11 -0
- package/dist/icons/icn-duplicate.svg +11 -0
- package/dist/icons/icn-edit.svg +11 -0
- package/dist/icons/icn-editar-withe.svg +3 -0
- package/dist/icons/icn-rename-white.svg +3 -0
- package/dist/icons/icn-rename.svg +3 -0
- package/dist/icons/icn-report-white.svg +11 -0
- package/dist/icons/icn-report.svg +11 -0
- package/dist/images/background-postmatch-template-01.jpg +0 -0
- package/dist/images/background-postmatch-template-02.jpg +0 -0
- package/dist/images/canchaRPH.svg +30 -0
- package/dist/index-B1R4W2EC.js +128151 -0
- package/dist/reports/background-postmatch-template-01@2x.jpg +0 -0
- package/dist/reports/background-postmatch-template-02@2x.jpg +0 -0
- package/dist/reports/thumbnail-portada-01@2x.png +0 -0
- package/dist/reports/thumbnail-portada-02@2x.png +0 -0
- package/dist/reports/thumbnail-portada-03@2x.png +0 -0
- package/dist/reports/thumbnail-portada-04@2x.png +0 -0
- package/dist/reports/thumbnail-portada-prmatch-01@2x.png +0 -0
- package/dist/reports/thumbnail-portada-prmatch-02@2x.png +0 -0
- package/dist/reports/thumbnail-portada-prmatch-03@2x.png +0 -0
- package/dist/reports/thumbnail-portada-prmatch-04@2x.png +0 -0
- package/dist/thumb1.png +0 -0
- package/dist/thumbnail-portada-01.jpg +0 -0
- package/dist/thumbnail-portada-02.jpg +0 -0
- package/dist/thumbnail-portada-03.jpg +0 -0
- package/dist/thumbnail-portada-04.jpg +0 -0
- package/dist/thumbnail-portada-prmatch-01.jpg +0 -0
- package/dist/thumbnail-portada-prmatch-02.jpg +0 -0
- package/dist/thumbnail-portada-prmatch-03.jpg +0 -0
- package/dist/thumbnail-portada-prmatch-04.jpg +0 -0
- package/package.json +70 -0
- package/src/App.vue +28 -0
- package/src/components/ReportsSection.vue +764 -0
- package/src/components/TemplatesSection.vue +911 -0
- package/src/components/elementsTemplates/ModalCreateTemplate.vue +407 -0
- package/src/components/elementsTemplates/ModalDeleteReport.vue +231 -0
- package/src/components/elementsTemplates/ModalDeleteTemplate.vue +234 -0
- package/src/components/elementsTemplates/ModalGenerarReporte.vue +1151 -0
- package/src/components/elementsTemplates/ModalRenameReporte.vue +315 -0
- package/src/components/elementsTemplates/ModalRenameTemplate.vue +320 -0
- package/src/components/elementsTemplates/ModalSoloEscritorio.vue +83 -0
- package/src/components/elementsTemplates/ModalduplicateTemplate.vue +283 -0
- package/src/components/elementsTemplates/ReportItem.vue +458 -0
- package/src/components/elementsTemplates/TemplateItem.vue +360 -0
- package/src/components/elementsTemplates/TooltipReportOptions.vue +85 -0
- package/src/components/elementsTemplates/TooltipTemplateOptions.vue +141 -0
- package/src/components/filters.vue +935 -0
- package/src/components/gsc-reports.vue +452 -0
- package/src/components/template-report-maker/CoverPage.vue +636 -0
- package/src/components/template-report-maker/CoverSelector.vue +165 -0
- package/src/components/template-report-maker/ReportAndTemplateMaker.vue +675 -0
- package/src/components/template-report-maker/ReportView.vue +66 -0
- package/src/components/template-report-maker/TemplateReportPage.vue +398 -0
- package/src/components/thumbnails-reports/AnalisisPostMatchType1.vue +741 -0
- package/src/components/thumbnails-reports/AnalisisPostMatchType2.vue +743 -0
- package/src/components/thumbnails-reports/AnalisisPostMatchType3.vue +463 -0
- package/src/components/thumbnails-reports/AnalisisPostMatchType4.vue +462 -0
- package/src/components/thumbnails-reports/AnalisisPrematchType1.vue +164 -0
- package/src/components/thumbnails-reports/AnalisisPrematchType2.vue +163 -0
- package/src/components/thumbnails-reports/AnalisisPrematchType3.vue +173 -0
- package/src/components/thumbnails-reports/AnalisisPrematchType4.vue +173 -0
- package/src/index.js +4 -0
- package/src/main.js +4 -0
- package/src/types.d.ts +45 -0
- package/src/utils/dateUtils.js +52 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="reports-section" ref="reportsSectionRef">
|
|
3
|
+
<div class="reports-header">
|
|
4
|
+
<span
|
|
5
|
+
>Reportes <span class="count">({{ filteredReports.length }})</span></span
|
|
6
|
+
>
|
|
7
|
+
<div class="sort-dropdown" ref="sortDropdownRef">
|
|
8
|
+
<button class="sort-button" @click="toggleSortDropdown">
|
|
9
|
+
{{ selectedSortOption || 'Ordenar' }}
|
|
10
|
+
<span class="dropdown-arrow" :class="{ rotated: showSortDropdown }"></span>
|
|
11
|
+
</button>
|
|
12
|
+
<div class="sort-options" v-if="showSortDropdown">
|
|
13
|
+
<div
|
|
14
|
+
v-for="option in sortOptions"
|
|
15
|
+
:key="option.value"
|
|
16
|
+
class="sort-option"
|
|
17
|
+
:class="{ selected: selectedSortOption === option.value }"
|
|
18
|
+
@click="selectedSortOption !== option.value && selectSortOption(option.value)"
|
|
19
|
+
>
|
|
20
|
+
<span>{{ option.label }}</span>
|
|
21
|
+
<span v-if="selectedSortOption === option.value" class="checkmark">
|
|
22
|
+
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
23
|
+
<path
|
|
24
|
+
d="M5 10.5L9 14.5L15 7.5"
|
|
25
|
+
stroke="#cbee6b"
|
|
26
|
+
stroke-width="2"
|
|
27
|
+
stroke-linecap="round"
|
|
28
|
+
stroke-linejoin="round"
|
|
29
|
+
/>
|
|
30
|
+
</svg>
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<!-- Estado de carga -->
|
|
37
|
+
<div v-if="loading" class="loading-state">
|
|
38
|
+
<div class="loading-spinner"></div>
|
|
39
|
+
<p>Cargando reportes...</p>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<!-- Estado de error -->
|
|
43
|
+
<div v-else-if="error" class="error-state">
|
|
44
|
+
<p>Error al cargar reportes: {{ error }}</p>
|
|
45
|
+
<button @click="loadReports" class="retry-button">Reintentar</button>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- Lista de reportes -->
|
|
49
|
+
<div v-else class="reports-grid" :class="gridClass" ref="reportsGridRef">
|
|
50
|
+
<ReportItem
|
|
51
|
+
v-for="report in filteredReports"
|
|
52
|
+
:key="report.id"
|
|
53
|
+
:report="report"
|
|
54
|
+
@open-report="onOpenReport"
|
|
55
|
+
@renombrar="onRenombrarReporte"
|
|
56
|
+
@eliminar="onEliminarReporte"
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<!-- Estado vacío -->
|
|
61
|
+
<div v-if="!loading && !error && reports.length === 0" class="empty-reports">
|
|
62
|
+
No tienes reportes aún.
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<!-- Estado de búsqueda sin resultados -->
|
|
66
|
+
<div
|
|
67
|
+
v-if="!loading && !error && reports.length > 0 && filteredReports.length === 0"
|
|
68
|
+
class="empty-reports"
|
|
69
|
+
>
|
|
70
|
+
No se encontraron reportes que coincidan con tu búsqueda.
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<!-- Modal para renombrar reporte -->
|
|
74
|
+
<ModalRenameReporte
|
|
75
|
+
v-if="showModalRenameReporte"
|
|
76
|
+
:initialName="renameReporteName"
|
|
77
|
+
:templateType="renameReporteTemplateType"
|
|
78
|
+
:token="token"
|
|
79
|
+
:userId="userId"
|
|
80
|
+
:reportId="renameReporteId"
|
|
81
|
+
@close="showModalRenameReporte = false"
|
|
82
|
+
@rename="onAcceptRenameReporte"
|
|
83
|
+
@refresh="loadReports"
|
|
84
|
+
/>
|
|
85
|
+
|
|
86
|
+
<!-- Modal para eliminar reporte -->
|
|
87
|
+
<ModalDeleteReport
|
|
88
|
+
v-if="showModalDeleteReporte"
|
|
89
|
+
:report-id="deleteReportId"
|
|
90
|
+
:user-id="userId"
|
|
91
|
+
:token="token"
|
|
92
|
+
@close="showModalDeleteReporte = false"
|
|
93
|
+
@report-deleted="onReportDeleted"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</template>
|
|
97
|
+
|
|
98
|
+
<script setup>
|
|
99
|
+
import { ref, onMounted, onBeforeUnmount, computed, nextTick } from 'vue'
|
|
100
|
+
import axios from 'axios'
|
|
101
|
+
import ReportItem from './elementsTemplates/ReportItem.vue'
|
|
102
|
+
import ModalRenameReporte from './elementsTemplates/ModalRenameReporte.vue'
|
|
103
|
+
import ModalDeleteReport from './elementsTemplates/ModalDeleteReport.vue'
|
|
104
|
+
|
|
105
|
+
// Definir las props
|
|
106
|
+
const props = defineProps({
|
|
107
|
+
userId: {
|
|
108
|
+
type: Number,
|
|
109
|
+
required: true,
|
|
110
|
+
},
|
|
111
|
+
team: {
|
|
112
|
+
type: Number,
|
|
113
|
+
required: true,
|
|
114
|
+
},
|
|
115
|
+
token: {
|
|
116
|
+
type: String,
|
|
117
|
+
required: true,
|
|
118
|
+
},
|
|
119
|
+
searchQuery: {
|
|
120
|
+
type: String,
|
|
121
|
+
default: '',
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const emit = defineEmits(['open-report'])
|
|
126
|
+
|
|
127
|
+
// Estado para los reportes
|
|
128
|
+
const reports = ref([])
|
|
129
|
+
const loading = ref(false)
|
|
130
|
+
const error = ref(null)
|
|
131
|
+
|
|
132
|
+
// Computed property para filtrar y ordenar reportes
|
|
133
|
+
const filteredReports = computed(() => {
|
|
134
|
+
let filtered = reports.value
|
|
135
|
+
|
|
136
|
+
// Aplicar filtro de búsqueda
|
|
137
|
+
if (props.searchQuery.trim()) {
|
|
138
|
+
const query = props.searchQuery.toLowerCase().trim()
|
|
139
|
+
|
|
140
|
+
filtered = reports.value.filter((report) => {
|
|
141
|
+
// Buscar por nombre del reporte
|
|
142
|
+
const reportName = report.report_name?.toLowerCase() || ''
|
|
143
|
+
if (reportName.includes(query)) {
|
|
144
|
+
return true
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Buscar por nombre del template
|
|
148
|
+
const templateName = report.name?.toLowerCase() || ''
|
|
149
|
+
if (templateName.includes(query)) {
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Buscar por fecha de creación
|
|
154
|
+
if (report.created_at) {
|
|
155
|
+
const createdDate = new Date(report.created_at)
|
|
156
|
+
const dateString = createdDate
|
|
157
|
+
.toLocaleDateString('es-ES', {
|
|
158
|
+
year: 'numeric',
|
|
159
|
+
month: 'long',
|
|
160
|
+
day: 'numeric',
|
|
161
|
+
})
|
|
162
|
+
.toLowerCase()
|
|
163
|
+
|
|
164
|
+
if (dateString.includes(query)) {
|
|
165
|
+
return true
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Buscar por fecha del juego
|
|
170
|
+
if (report.game?.date_time_utc) {
|
|
171
|
+
const gameDate = new Date(report.game.date_time_utc)
|
|
172
|
+
const gameDateString = gameDate
|
|
173
|
+
.toLocaleDateString('es-ES', {
|
|
174
|
+
year: 'numeric',
|
|
175
|
+
month: 'long',
|
|
176
|
+
day: 'numeric',
|
|
177
|
+
})
|
|
178
|
+
.toLowerCase()
|
|
179
|
+
|
|
180
|
+
if (gameDateString.includes(query)) {
|
|
181
|
+
return true
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Buscar por nombre de la temporada
|
|
186
|
+
const seasonName = report.game?.season_name?.toLowerCase() || ''
|
|
187
|
+
if (seasonName.includes(query)) {
|
|
188
|
+
return true
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Buscar por nombre del torneo/liga
|
|
192
|
+
const tournamentName = report.tournament_name?.toLowerCase() || ''
|
|
193
|
+
if (tournamentName.includes(query)) {
|
|
194
|
+
return true
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Buscar por jornada
|
|
198
|
+
if (report.game?.matchday) {
|
|
199
|
+
const matchday = report.game.matchday.toString()
|
|
200
|
+
if (matchday.includes(query)) {
|
|
201
|
+
return true
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return false
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Aplicar ordenamiento
|
|
210
|
+
if (selectedSortOption.value) {
|
|
211
|
+
filtered = [...filtered].sort((a, b) => {
|
|
212
|
+
if (selectedSortOption.value === 'A - Z') {
|
|
213
|
+
// Ordenar alfabéticamente por nombre del reporte
|
|
214
|
+
const nameA = (a.report_name || '').toLowerCase()
|
|
215
|
+
const nameB = (b.report_name || '').toLowerCase()
|
|
216
|
+
return nameA.localeCompare(nameB, 'es', { sensitivity: 'base' })
|
|
217
|
+
} else if (selectedSortOption.value === 'Más recientes') {
|
|
218
|
+
// Ordenar por fecha de creación (más recientes primero)
|
|
219
|
+
const dateA = new Date(a.created_at || 0)
|
|
220
|
+
const dateB = new Date(b.created_at || 0)
|
|
221
|
+
return dateB - dateA
|
|
222
|
+
} else if (selectedSortOption.value === 'Torneo') {
|
|
223
|
+
// Ordenar primero por nombre del torneo y luego por season_id
|
|
224
|
+
const torneoA = (a.tournament_name || '').toLowerCase()
|
|
225
|
+
const torneoB = (b.tournament_name || '').toLowerCase()
|
|
226
|
+
|
|
227
|
+
// Si los nombres de torneo son diferentes, ordenar por nombre
|
|
228
|
+
if (torneoA !== torneoB) {
|
|
229
|
+
return torneoA.localeCompare(torneoB, 'es', { sensitivity: 'base' })
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Si los nombres de torneo son iguales, ordenar por season_id (mayor a menor)
|
|
233
|
+
const seasonIdA = a.season_id || 0
|
|
234
|
+
const seasonIdB = b.season_id || 0
|
|
235
|
+
return seasonIdB - seasonIdA
|
|
236
|
+
} else if (selectedSortOption.value === 'Jornada') {
|
|
237
|
+
// Ordenar por matchday_id
|
|
238
|
+
const matchdayA = a.game?.matchday_id || 0
|
|
239
|
+
const matchdayB = b.game?.matchday_id || 0
|
|
240
|
+
return matchdayA - matchdayB
|
|
241
|
+
}
|
|
242
|
+
return 0
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return filtered
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
const showSortDropdown = ref(false)
|
|
250
|
+
const selectedSortOption = ref('Más recientes') // Opción por defecto
|
|
251
|
+
const showModalRenameReporte = ref(false)
|
|
252
|
+
const renameReporteName = ref('')
|
|
253
|
+
const renameReporteId = ref('')
|
|
254
|
+
const renameReporteTemplateType = ref('')
|
|
255
|
+
const showModalDeleteReporte = ref(false)
|
|
256
|
+
const deleteReporteName = ref('')
|
|
257
|
+
const deleteReportId = ref('')
|
|
258
|
+
const sortDropdownRef = ref(null)
|
|
259
|
+
const reportsSectionRef = ref(null)
|
|
260
|
+
const reportsGridRef = ref(null)
|
|
261
|
+
const containerWidth = ref(0)
|
|
262
|
+
|
|
263
|
+
const sortOptions = [
|
|
264
|
+
{ label: 'A - Z', value: 'A - Z' },
|
|
265
|
+
{ label: 'Más recientes', value: 'Más recientes' },
|
|
266
|
+
{ label: 'Torneo', value: 'Torneo' },
|
|
267
|
+
{ label: 'Jornada', value: 'Jornada' },
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
// Función para cargar los reportes
|
|
271
|
+
const loadReports = async () => {
|
|
272
|
+
loading.value = true
|
|
273
|
+
error.value = null
|
|
274
|
+
|
|
275
|
+
try {
|
|
276
|
+
const response = await axios.get(
|
|
277
|
+
`https://m9qip57rsh.execute-api.us-east-2.amazonaws.com/prod/users/${props.userId}/reports`,
|
|
278
|
+
{
|
|
279
|
+
headers: {
|
|
280
|
+
Authorization: `${props.token}`,
|
|
281
|
+
'Content-Type': 'application/json',
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
// Verificar la estructura de la respuesta
|
|
287
|
+
if (response.data && Array.isArray(response.data)) {
|
|
288
|
+
reports.value = response.data
|
|
289
|
+
} else if (response.data && response.data.reports) {
|
|
290
|
+
reports.value = response.data.reports
|
|
291
|
+
} else if (response.data && response.data.data) {
|
|
292
|
+
reports.value = response.data.data
|
|
293
|
+
} else {
|
|
294
|
+
reports.value = []
|
|
295
|
+
}
|
|
296
|
+
} catch (err) {
|
|
297
|
+
console.error('Error cargando reportes:', err)
|
|
298
|
+
console.error('Error response:', err.response)
|
|
299
|
+
error.value = err.message || 'Error al cargar los reportes'
|
|
300
|
+
reports.value = [] // Asegurar que esté vacío en caso de error
|
|
301
|
+
} finally {
|
|
302
|
+
loading.value = false
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Computed property para determinar las clases del grid basado en el ancho del contenedor
|
|
307
|
+
const gridClass = computed(() => {
|
|
308
|
+
if (!containerWidth.value) return 'grid-1-column'
|
|
309
|
+
|
|
310
|
+
// Calculamos cuántos items caben en el ancho disponible
|
|
311
|
+
const itemWidth = 340 // Ancho base del ReportItem
|
|
312
|
+
const gap = 20 // Gap entre items
|
|
313
|
+
const padding = 40 // Padding del contenedor (20px * 2)
|
|
314
|
+
|
|
315
|
+
// Ancho disponible para el grid
|
|
316
|
+
const availableWidth = containerWidth.value - padding
|
|
317
|
+
|
|
318
|
+
// Calculamos cuántos items caben considerando el gap
|
|
319
|
+
// Para n items necesitamos: n * itemWidth + (n-1) * gap
|
|
320
|
+
// Despejando: n = (availableWidth + gap) / (itemWidth + gap)
|
|
321
|
+
const itemsPerRow = Math.floor((availableWidth + gap) / (itemWidth + gap))
|
|
322
|
+
|
|
323
|
+
// Aseguramos que al menos tengamos 1 columna
|
|
324
|
+
const finalItemsPerRow = Math.max(1, itemsPerRow)
|
|
325
|
+
|
|
326
|
+
if (finalItemsPerRow >= 4) {
|
|
327
|
+
return 'grid-4-columns'
|
|
328
|
+
} else if (finalItemsPerRow >= 3) {
|
|
329
|
+
return 'grid-3-columns'
|
|
330
|
+
} else if (finalItemsPerRow >= 2) {
|
|
331
|
+
return 'grid-2-columns'
|
|
332
|
+
} else {
|
|
333
|
+
return 'grid-1-column'
|
|
334
|
+
}
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
const toggleSortDropdown = () => {
|
|
338
|
+
showSortDropdown.value = !showSortDropdown.value
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const selectSortOption = (option) => {
|
|
342
|
+
console.log('Ordenando por:', option)
|
|
343
|
+
selectedSortOption.value = option
|
|
344
|
+
showSortDropdown.value = false
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function onOpenReport(report) {
|
|
348
|
+
console.log('reports section onOpenReport', report)
|
|
349
|
+
// Emitir un evento o manejar la lógica para abrir el reporte
|
|
350
|
+
// Por ejemplo, podrías redirigir a una página de reporte específica
|
|
351
|
+
// router.push(`/reports/${report.id}`)
|
|
352
|
+
emit('open-report', report)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const onRenombrarReporte = (nombre, reportId) => {
|
|
356
|
+
renameReporteName.value = nombre
|
|
357
|
+
renameReporteId.value = reportId
|
|
358
|
+
// Buscar el reporte para obtener el template_type
|
|
359
|
+
const report = reports.value.find((r) => r.id === reportId)
|
|
360
|
+
renameReporteTemplateType.value = report ? report.template_type : ''
|
|
361
|
+
showModalRenameReporte.value = true
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const onAcceptRenameReporte = (nuevoNombre) => {
|
|
365
|
+
console.log('Renombrar reporte de', renameReporteName.value, 'a', nuevoNombre)
|
|
366
|
+
showModalRenameReporte.value = false
|
|
367
|
+
|
|
368
|
+
// Actualizar el nombre del reporte en la lista local
|
|
369
|
+
const reportIndex = reports.value.findIndex((r) => r.id === renameReporteId.value)
|
|
370
|
+
if (reportIndex !== -1) {
|
|
371
|
+
reports.value[reportIndex].report_name = nuevoNombre
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const onEliminarReporte = (report) => {
|
|
376
|
+
deleteReporteName.value = report.report_name || 'Reporte'
|
|
377
|
+
deleteReportId.value = report.id
|
|
378
|
+
showModalDeleteReporte.value = true
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const onReportDeleted = (reportId) => {
|
|
382
|
+
showModalDeleteReporte.value = false
|
|
383
|
+
|
|
384
|
+
// Remover el reporte eliminado de la lista
|
|
385
|
+
reports.value = reports.value.filter((report) => report.id !== reportId)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const handleClickOutside = (event) => {
|
|
389
|
+
if (
|
|
390
|
+
showSortDropdown.value &&
|
|
391
|
+
sortDropdownRef.value &&
|
|
392
|
+
!sortDropdownRef.value.contains(event.target)
|
|
393
|
+
) {
|
|
394
|
+
showSortDropdown.value = false
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Función para actualizar el ancho del contenedor
|
|
399
|
+
const updateContainerWidth = () => {
|
|
400
|
+
if (reportsSectionRef.value) {
|
|
401
|
+
containerWidth.value = reportsSectionRef.value.offsetWidth
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Resize observer para detectar cambios en el tamaño del contenedor
|
|
406
|
+
let resizeObserver = null
|
|
407
|
+
|
|
408
|
+
onMounted(async () => {
|
|
409
|
+
document.addEventListener('mousedown', handleClickOutside)
|
|
410
|
+
|
|
411
|
+
// Cargar los reportes al montar el componente
|
|
412
|
+
await loadReports()
|
|
413
|
+
|
|
414
|
+
// Esperar a que el DOM esté completamente renderizado
|
|
415
|
+
await nextTick()
|
|
416
|
+
|
|
417
|
+
// Inicializar el ancho del contenedor
|
|
418
|
+
updateContainerWidth()
|
|
419
|
+
|
|
420
|
+
// Configurar el ResizeObserver para detectar cambios en el tamaño
|
|
421
|
+
if (window.ResizeObserver) {
|
|
422
|
+
resizeObserver = new ResizeObserver(() => {
|
|
423
|
+
updateContainerWidth()
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
if (reportsSectionRef.value) {
|
|
427
|
+
resizeObserver.observe(reportsSectionRef.value)
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
// Fallback para navegadores que no soportan ResizeObserver
|
|
431
|
+
window.addEventListener('resize', updateContainerWidth)
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
onBeforeUnmount(() => {
|
|
436
|
+
document.removeEventListener('mousedown', handleClickOutside)
|
|
437
|
+
|
|
438
|
+
if (resizeObserver) {
|
|
439
|
+
resizeObserver.disconnect()
|
|
440
|
+
} else {
|
|
441
|
+
window.removeEventListener('resize', updateContainerWidth)
|
|
442
|
+
}
|
|
443
|
+
})
|
|
444
|
+
</script>
|
|
445
|
+
|
|
446
|
+
<style scoped>
|
|
447
|
+
.reports-section {
|
|
448
|
+
padding: 24px 20px;
|
|
449
|
+
text-align: center;
|
|
450
|
+
border-radius: 8px;
|
|
451
|
+
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.25);
|
|
452
|
+
background-color: rgba(38, 50, 60, 0.4);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.reports-header {
|
|
456
|
+
display: flex;
|
|
457
|
+
justify-content: space-between;
|
|
458
|
+
align-items: center;
|
|
459
|
+
margin-bottom: 20px;
|
|
460
|
+
font-family: Poppins-Medium;
|
|
461
|
+
font-size: 20px;
|
|
462
|
+
font-weight: 500;
|
|
463
|
+
font-stretch: normal;
|
|
464
|
+
font-style: normal;
|
|
465
|
+
line-height: normal;
|
|
466
|
+
letter-spacing: normal;
|
|
467
|
+
text-align: left;
|
|
468
|
+
color: #fff;
|
|
469
|
+
position: relative;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.reports-header::after {
|
|
473
|
+
content: '';
|
|
474
|
+
position: absolute;
|
|
475
|
+
bottom: -20px;
|
|
476
|
+
left: 50%;
|
|
477
|
+
transform: translateX(-50%);
|
|
478
|
+
width: 100%;
|
|
479
|
+
height: 1px;
|
|
480
|
+
background-color: #3d4a54;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.count {
|
|
484
|
+
color: #8b98a9;
|
|
485
|
+
font-size: 9px;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.sort-dropdown {
|
|
489
|
+
position: relative;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.sort-button {
|
|
493
|
+
width: 148px;
|
|
494
|
+
height: 40px;
|
|
495
|
+
border-radius: 8px;
|
|
496
|
+
background-color: rgba(255, 255, 255, 0.04);
|
|
497
|
+
font-family: Poppins-Regular;
|
|
498
|
+
font-size: 14px;
|
|
499
|
+
font-weight: normal;
|
|
500
|
+
font-stretch: normal;
|
|
501
|
+
font-style: normal;
|
|
502
|
+
line-height: 1.71;
|
|
503
|
+
letter-spacing: normal;
|
|
504
|
+
text-align: left;
|
|
505
|
+
color: #fff;
|
|
506
|
+
border: none;
|
|
507
|
+
padding: 8px 12px;
|
|
508
|
+
cursor: pointer;
|
|
509
|
+
display: flex;
|
|
510
|
+
justify-content: space-between;
|
|
511
|
+
align-items: center;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.sort-button:hover {
|
|
515
|
+
background-color: rgba(255, 255, 255, 0.08);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.dropdown-arrow {
|
|
519
|
+
width: 8px;
|
|
520
|
+
height: 8px;
|
|
521
|
+
position: relative;
|
|
522
|
+
transition: transform 0.2s;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.dropdown-arrow::before,
|
|
526
|
+
.dropdown-arrow::after {
|
|
527
|
+
content: '';
|
|
528
|
+
position: absolute;
|
|
529
|
+
background-color: #fff;
|
|
530
|
+
width: 1px;
|
|
531
|
+
height: 6px;
|
|
532
|
+
top: 1px;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
.dropdown-arrow::before {
|
|
536
|
+
left: 2px;
|
|
537
|
+
transform: rotate(45deg);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.dropdown-arrow::after {
|
|
541
|
+
right: 2px;
|
|
542
|
+
transform: rotate(-45deg);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.dropdown-arrow.rotated {
|
|
546
|
+
transform: rotate(0deg);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.dropdown-arrow {
|
|
550
|
+
transform: rotate(180deg);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.sort-options {
|
|
554
|
+
position: absolute;
|
|
555
|
+
top: 100%;
|
|
556
|
+
right: 0;
|
|
557
|
+
left: auto;
|
|
558
|
+
width: 206px;
|
|
559
|
+
height: 146px;
|
|
560
|
+
background-color: #2e3b46;
|
|
561
|
+
border-radius: 12px;
|
|
562
|
+
margin-top: 4px;
|
|
563
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
564
|
+
z-index: 3200;
|
|
565
|
+
overflow: hidden;
|
|
566
|
+
padding: 0;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.sort-option {
|
|
570
|
+
display: flex;
|
|
571
|
+
align-items: center;
|
|
572
|
+
justify-content: space-between;
|
|
573
|
+
flex-grow: 0;
|
|
574
|
+
font-family: Poppins-Regular;
|
|
575
|
+
font-size: 13px;
|
|
576
|
+
font-weight: normal;
|
|
577
|
+
font-stretch: normal;
|
|
578
|
+
font-style: normal;
|
|
579
|
+
line-height: 1.5;
|
|
580
|
+
letter-spacing: normal;
|
|
581
|
+
text-align: left;
|
|
582
|
+
color: #fff;
|
|
583
|
+
cursor: pointer;
|
|
584
|
+
transition:
|
|
585
|
+
background-color 0.2s,
|
|
586
|
+
color 0.2s;
|
|
587
|
+
background: none;
|
|
588
|
+
padding: 14px 18px;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.sort-option.selected {
|
|
592
|
+
color: #cbee6b;
|
|
593
|
+
background-color: rgba(255, 255, 255, 0.1);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
.sort-option:hover {
|
|
597
|
+
background-color: rgba(255, 255, 255, 0.08);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.sort-option:not(:last-child) {
|
|
601
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.checkmark {
|
|
605
|
+
width: 18px;
|
|
606
|
+
height: 18px;
|
|
607
|
+
display: flex;
|
|
608
|
+
align-items: center;
|
|
609
|
+
justify-content: center;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.checkmark svg {
|
|
613
|
+
width: 16px;
|
|
614
|
+
height: 16px;
|
|
615
|
+
color: #cbee6b;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/* Base styles para reports-grid */
|
|
619
|
+
.reports-grid {
|
|
620
|
+
display: grid;
|
|
621
|
+
gap: 20px;
|
|
622
|
+
margin-top: 38px;
|
|
623
|
+
width: 100%;
|
|
624
|
+
justify-items: center;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/* Clases dinámicas basadas en el número de columnas que caben */
|
|
628
|
+
.grid-4-columns {
|
|
629
|
+
grid-template-columns: repeat(4, 340px);
|
|
630
|
+
gap: 20px;
|
|
631
|
+
justify-content: center;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.grid-3-columns {
|
|
635
|
+
grid-template-columns: repeat(3, 340px);
|
|
636
|
+
gap: 20px;
|
|
637
|
+
justify-content: center;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.grid-2-columns {
|
|
641
|
+
grid-template-columns: repeat(2, 340px);
|
|
642
|
+
gap: 20px;
|
|
643
|
+
justify-content: center;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.grid-1-column {
|
|
647
|
+
grid-template-columns: 340px;
|
|
648
|
+
gap: 20px;
|
|
649
|
+
justify-content: center;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/* Ajustes responsivos para el contenedor y header */
|
|
653
|
+
.grid-1-column .reports-section {
|
|
654
|
+
padding: 16px 12px;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.grid-2-columns .reports-section {
|
|
658
|
+
padding: 20px 16px;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.grid-1-column .reports-header {
|
|
662
|
+
font-size: 18px;
|
|
663
|
+
margin-bottom: 16px;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
.grid-2-columns .reports-header {
|
|
667
|
+
font-size: 19px;
|
|
668
|
+
margin-bottom: 18px;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
.grid-1-column .sort-button {
|
|
672
|
+
width: 120px;
|
|
673
|
+
height: 36px;
|
|
674
|
+
font-size: 12px;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.grid-2-columns .sort-button {
|
|
678
|
+
width: 130px;
|
|
679
|
+
height: 38px;
|
|
680
|
+
font-size: 13px;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* Asegurar que los items del grid mantengan su tamaño */
|
|
684
|
+
.reports-grid .report-card {
|
|
685
|
+
width: 340px;
|
|
686
|
+
height: 358px;
|
|
687
|
+
flex-shrink: 0;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* Optimización para pantallas muy pequeñas */
|
|
691
|
+
@media (max-width: 400px) {
|
|
692
|
+
.reports-grid {
|
|
693
|
+
gap: 16px;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.reports-grid .report-card {
|
|
697
|
+
width: 320px;
|
|
698
|
+
height: 338px;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.grid-1-column {
|
|
702
|
+
grid-template-columns: 320px;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.empty-reports {
|
|
707
|
+
color: #8b98a9;
|
|
708
|
+
font-size: 20px;
|
|
709
|
+
margin-top: 40px;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/* Estados de carga y error */
|
|
713
|
+
.loading-state,
|
|
714
|
+
.error-state {
|
|
715
|
+
display: flex;
|
|
716
|
+
flex-direction: column;
|
|
717
|
+
align-items: center;
|
|
718
|
+
justify-content: center;
|
|
719
|
+
padding: 60px 20px;
|
|
720
|
+
text-align: center;
|
|
721
|
+
color: #fff;
|
|
722
|
+
font-family: 'Poppins-Regular', sans-serif;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.loading-spinner {
|
|
726
|
+
width: 40px;
|
|
727
|
+
height: 40px;
|
|
728
|
+
border: 3px solid rgba(255, 255, 255, 0.3);
|
|
729
|
+
border-top: 3px solid #cbee6b;
|
|
730
|
+
border-radius: 50%;
|
|
731
|
+
animation: spin 1s linear infinite;
|
|
732
|
+
margin-bottom: 16px;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
@keyframes spin {
|
|
736
|
+
0% {
|
|
737
|
+
transform: rotate(0deg);
|
|
738
|
+
}
|
|
739
|
+
100% {
|
|
740
|
+
transform: rotate(360deg);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
.error-state p {
|
|
745
|
+
margin-bottom: 16px;
|
|
746
|
+
color: #ff6b6b;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
.retry-button {
|
|
750
|
+
background: linear-gradient(90deg, #cbee6b 0%, #b6e14b 100%);
|
|
751
|
+
border: none;
|
|
752
|
+
border-radius: 8px;
|
|
753
|
+
color: #1a2a3a;
|
|
754
|
+
font-family: 'Poppins-Medium', sans-serif;
|
|
755
|
+
font-size: 14px;
|
|
756
|
+
padding: 10px 20px;
|
|
757
|
+
cursor: pointer;
|
|
758
|
+
transition: opacity 0.2s;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.retry-button:hover {
|
|
762
|
+
opacity: 0.8;
|
|
763
|
+
}
|
|
764
|
+
</style>
|