158 lines
5.7 KiB
Vue
158 lines
5.7 KiB
Vue
<template>
|
|
<div id="pdf-content" class="space-y-4 bg-surface text-accent">
|
|
<h2 class="text-3xl font-semibold text-center">{{ data.title[langcode] }}</h2>
|
|
<p class="text-center text-muted">{{ data.subtitle[langcode] }}</p>
|
|
<!-- <div class="text-center">
|
|
<h3 class="text-lg font-semibold my-4">Tu puntuación total es {{ totalScore?.score }}/{{ totalScore?.totalPossiblePoints }}</h3>
|
|
<p v-if="totalScore?.recommendations" class="text-lg font-semibold my-4">Recomendarión: {{ totalScore?.recommendations[langcode] }}</p>
|
|
</div> -->
|
|
<section v-for="(res, index) in results" :key="index" class="border border-border rounded-2xl">
|
|
<div v-if="res.results[0] !== 'SIN REGLA'" class="flex flex-col gap-2 justify-start items-center p-6 mb-4">
|
|
<div class="w-full flex flex-row justify-center items-center gap-2 border-b border-border pb-4">
|
|
<h3 class="font-semibold text-xl">{{ res.sectionTitle[langcode] }}</h3>
|
|
<img src="../assets/img/x-cross.png" alt="cruz roja" class="h-6 w-6">
|
|
<!-- <div class="flex gap-4 justify-end items-center w-full">
|
|
<p class="text-muted">Puntuación</p>
|
|
<div class="p-1 rounded-xl bg-[#DAB2F4] flex justify-center min-w-20"><p>{{ res.score }}/{{ res.sectionPossibleTotalPoints }}</p></div>
|
|
</div> -->
|
|
</div>
|
|
<div v-for="(item, index) in res.results" :key="index" class="flex flex-col">
|
|
<p v-if="item[langcode] !== ''" class="text-sm mb-2" v-html="item[langcode]"></p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
<p class="my-4">{{ langcode === 'es' ? 'Revisa la aplicación normativa con Asesoría Jurídica de tu universidad' : 'Reveja a aplicação normativa com a Assessoria Jurídica da sua universidade' }}</p>
|
|
<client-only>
|
|
<div class="flex justify-center gap-2 mt-4">
|
|
<ButtonCTA color="transparent" @click="reloadPage">
|
|
{{ langcode === 'es' ? 'Cerrar asistente' : 'Fechar assistente' }}
|
|
</ButtonCTA>
|
|
<ButtonCTA color="accent" @click="downloadPDF">
|
|
{{ langcode === 'es' ? 'Descargar Informe (PDF)' : 'Baixar Relatório (PDF)' }}
|
|
</ButtonCTA>
|
|
</div>
|
|
</client-only>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters } from 'vuex';
|
|
export default {
|
|
name: "SliceEnd",
|
|
props: {
|
|
|
|
data: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
currentIndex: { type: Number, default: 0 },
|
|
total: { type: Number, default: 1 }
|
|
},
|
|
emits: ['previous'],
|
|
data() {
|
|
return {
|
|
results: null,
|
|
totalScore: null,
|
|
recommendations: [
|
|
"Implementar una estrategia de comunicación interna.",
|
|
"Evaluar la satisfacción del equipo trimestralmente.",
|
|
"Adoptar un sistema de gestión de proyectos colaborativo."
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters(['langcode'])
|
|
},
|
|
mounted() {
|
|
//this.getResults();
|
|
this.getGroupedResults();
|
|
},
|
|
methods: {
|
|
getResults() {
|
|
this.results = JSON.parse(localStorage.getItem('results'));
|
|
this.totalScore = JSON.parse(localStorage.getItem('final-score'));
|
|
},
|
|
getGroupedResults() {
|
|
const storedResults = localStorage.getItem("results")
|
|
if (!storedResults) return []
|
|
|
|
const results = JSON.parse(storedResults)
|
|
|
|
const grouped = {}
|
|
|
|
results.forEach(item => {
|
|
// Extraer el grupo principal del sectionId, ej. "P8" de "P8_1"
|
|
const groupId = item.sectionId.split("_")[0] || item.sectionId
|
|
|
|
// Si no existe el grupo, lo inicializamos
|
|
if (!grouped[groupId]) {
|
|
grouped[groupId] = {
|
|
sectionGroup: groupId,
|
|
sectionTitle: item.sectionTitle,
|
|
results: [],
|
|
}
|
|
}
|
|
|
|
// Solo añadimos si tiene contenido útil
|
|
if (
|
|
item.result &&
|
|
(
|
|
(item.result.es && item.result.es.trim() !== "") ||
|
|
(item.result.pt && item.result.pt.trim() !== "")
|
|
)
|
|
) {
|
|
grouped[groupId].results.push(item.result)
|
|
}
|
|
})
|
|
|
|
// Convertir a array y eliminar grupos vacíos
|
|
this.results = Object.values(grouped).filter(
|
|
group => group.results.length > 0
|
|
)
|
|
localStorage.setItem("grouped-results", JSON.stringify(this.results))
|
|
},
|
|
reloadPage() {
|
|
if (import.meta.client) {
|
|
window.location.reload();
|
|
}
|
|
},
|
|
async downloadPDF() {
|
|
if (import.meta.client) {
|
|
const { jsPDF } = await import("jspdf")
|
|
const html2canvas = (await import("html2canvas")).default
|
|
|
|
const content = document.getElementById("pdf-content")
|
|
|
|
// // Parchear colores 'oklch' -> hex (html2canvas workaround)
|
|
// content.querySelectorAll("*").forEach(el => {
|
|
// const style = getComputedStyle(el)
|
|
// if (style.color.includes("oklch")) el.style.color = "#DAB2F4"
|
|
// if (style.backgroundColor.includes("oklch")) el.style.backgroundColor = "#eef2ff"
|
|
// if (style.borderColor.includes("oklch")) el.style.borderColor = "#DAB2F4"
|
|
// })
|
|
|
|
|
|
const canvas = await html2canvas(content, { scale: 2, backgroundColor: "#ffffff" })
|
|
const imgData = canvas.toDataURL("image/png")
|
|
|
|
const pdf = new jsPDF("p", "mm", "a4")
|
|
const pageWidth = pdf.internal.pageSize.getWidth()
|
|
const pageHeight = pdf.internal.pageSize.getHeight()
|
|
|
|
// Definir márgenes (ejemplo: 20mm)
|
|
const margin = 20
|
|
const pdfWidth = pageWidth - 2 * margin
|
|
const pdfHeight = (canvas.height * pdfWidth) / canvas.width
|
|
pdf.setFontSize(12)
|
|
|
|
// Si el contenido es más alto que la página, ajustamos para que se pueda dividir en varias páginas
|
|
pdf.addImage(imgData, "PNG", 20, 20, pdfWidth, pdfHeight)
|
|
pdf.save("recomendaciones.pdf")
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
</script>
|