Skip to content

Commit

Permalink
fix fossasia#89 get and display badge fields, however, print pdf not …
Browse files Browse the repository at this point in the history
…working yet
  • Loading branch information
shaunBoahCodes committed Aug 10, 2023
1 parent f1a47a3 commit 5970680
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 97 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"dependencies": {
"@headlessui/vue": "^1.7.14",
"@heroicons/vue": "^2.0.18",
"dayjs": "^1.11.9",
"mande": "^2.0.6",
"pinia": "^2.1.3",
"vue": "^3.3.4",
Expand Down
5 changes: 3 additions & 2 deletions src/components/Modals/PrintModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ const printDelay = (delayHideModal, delayPrint) => {
const print = () => {
if (props.validQRCode) {
printModalStore.printOptions.forEach((element) => (element.disabled = true))
printModalStore.printOptions.forEach((option) => (option.disabled = true))
printingText.value = true
disableButton.value = true
console.log(printModalStore.selectedOptions)
printModalStore.getPDF()
printDelay(3000, 3200)
} else {
printDelay(0, 200)
Expand Down
11 changes: 9 additions & 2 deletions src/components/Registration/Manual/ScanSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import StandardButton from '@/components/Shared/StandardButton.vue'
import SuccessNotification from '@/components/Shared/SuccessNotification.vue'
import { useScannerStore } from '@/stores/scanner'
import { useSearchAttendeeStore } from '@/stores/searchAttendee'
import { usePrintModalStore } from '@/stores/printModal'
const scannerStore = useScannerStore()
const searchAttendeeStore = useSearchAttendeeStore()
const printModalStore = usePrintModalStore()
// get scanner type from vue router params
const route = useRoute()
const scannerType = route.params.scannerType
const eventId = route.params.eventId
const camera = ref('front')
const showPrintModal = ref(false)
Expand Down Expand Up @@ -71,7 +74,7 @@ async function logErrors(promise) {
:camera="camera"
@init="logErrors"
@decode="
;async () => {
async () => {
validQRCode = await scannerStore
.checkInAttendeeScanner()
.then(() => (showPrintModal = true))
Expand All @@ -89,7 +92,11 @@ async function logErrors(promise) {
<div class="w-full"></div>
</div>
<div class="grow">
<SearchAttendee @print="showPrintModal = true" />
<SearchAttendee @print="
async ($event) => {
await printModalStore.getBadgeFields($event)
showPrintModal = true
}" />
</div>
</div>
</template>
31 changes: 16 additions & 15 deletions src/components/Registration/Manual/SearchAttendee.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { ref, watch } from 'vue'
import { onMounted, ref, watch } from 'vue'
import { XCircleIcon, PrinterIcon, MagnifyingGlassIcon } from '@heroicons/vue/20/solid'
import { FunnelIcon } from '@heroicons/vue/24/outline'
Expand All @@ -26,6 +26,10 @@ watch(query, (newValue) => {
searchAttendeeStore.getAttendee(newValue, route.params.eventId)
}
})
onMounted(() => {
searchAttendeeStore.getTicketDetails(eventId)
})
</script>

<template>
Expand Down Expand Up @@ -147,19 +151,16 @@ watch(query, (newValue) => {
class="flex flex-wrap text-normal gap-1 mt-1 sm:mt-0"
>
<span
v-if="searchAttendeeStore.filterOptions[0].show"
class="text-center rounded-md px-2 py-1 text-xs text-gray-600 ring-1 ring-inset ring-gray-500/10"
>{{ person.info.role }}</span
>
<span
v-if="searchAttendeeStore.filterOptions[1].show"
class="text-center rounded-md px-2 bg-yellow-50 py-1 text-xs font-medium text-yellow-800 ring-1 ring-inset ring-yellow-600/20"
>{{ person.info.memberType }}</span
>
<span
v-if="searchAttendeeStore.filterOptions[2].show"
class="text-center rounded-md px-2 bg-gray-50 py-1 text-xs font-bold text-gray-600 ring-1 ring-inset ring-gray-500/10"
>{{ person.info.organisation }}</span
v-for="(option, index) in searchAttendeeStore.filterOptions"
:key="index"
v-show="searchAttendeeStore.filterOptions[index].show && person.info[index].value !== null"
:class="[
person.info[index].name === 'Ticket Type'
? 'text-yellow-600 font-semibold ring-yellow-600/20'
: 'text-gray-600 ring-gray-500/10',
'text-center rounded-md px-2 py-1 text-xs ring-1 ring-inset'
]"
>{{ person.info[index].value }}</span
>
</div>
</div>
Expand All @@ -185,7 +186,7 @@ watch(query, (newValue) => {
text="Print"
:icon="PrinterIcon"
class="bg-yellow-300 text-gray-900 hover:bg-yellow-200 w-1/2 sm:w-auto justify-center"
@click="emit('print', person.name)"
@click="emit('print', { attendeeId: person.id, ticketId: person.ticketId})"
/>
</div>
</div>
Expand Down
1 change: 0 additions & 1 deletion src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import RegistrationManual from '@/components/Registration/Manual/ScanSearch.vue'
import RegistrationStats from '@/components/Registration/Manual/RegistrationStats.vue'
import NotFound from '@/views/NotFound.vue'
import AuthTemplate from '@/AuthTemplate.vue'
import RegistrationStats from '@/components/Registration/Manual/RegistrationStats.vue'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
Expand Down
163 changes: 113 additions & 50 deletions src/stores/printModal.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,16 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { useApiStore } from '@/stores/api'

export const usePrintModalStore = defineStore('printModal', () => {
const printOptions = [
{
id: 'code',
name: 'code',
label: 'QR Code',
checked: ref(true),
disabled: true
},
{
id: 'name',
name: 'name',
label: 'Name',
checked: ref(true),
disabled: false
},
{
id: 'email',
name: 'email',
label: 'Email',
checked: ref(true),
disabled: false
},
{
id: 'org',
name: 'org',
label: 'Organisation',
checked: ref(true),
disabled: false
},
{
id: 'role',
name: 'role',
label: 'Role',
checked: ref(true),
disabled: false
}
]
const attendeeId = ref(null)
//for user interaction
const printOptions = ref([])

//id of all options
const allOptions = ref([])
//updates when checked
const selectedOptions = ref(['code', 'name', 'email', 'org', 'role'])
const selectedOptions = ref([])

function selectOption(option) {
option.checked = !option.checked
Expand All @@ -54,29 +23,123 @@ export const usePrintModalStore = defineStore('printModal', () => {

function selectOrDeselectAll() {
if (selectedOptions.value.length === 5) {
printOptions.forEach((option) => {
if (option.id !== 'code') {
option.checked.value = false
selectedOptions.value = ['code']
printOptions.value.forEach((option) => {
if (option.name !== 'code') {
option.checked = false
selectedOptions.value = allOptions.value.find((option) => option.name === 'code')
}
})
} else {
printOptions.forEach((option) => {
option.checked.value = true
selectedOptions.value = ['code', 'name', 'email', 'org', 'role']
printOptions.value.forEach((option) => {
option.checked = true
selectedOptions.value = allOptions.value
})
}
}

function reset() {
selectedOptions.value = ['code', 'name', 'email', 'org', 'role']
printOptions.forEach((option) => {
if (option.id !== 'code') {
selectedOptions.value = allOptions.value
printOptions.value.forEach((option) => {
if (option.name !== 'code') {
option.disabled = false
option.checked.value = true
option.checked = true
}
})
}

return { printOptions, selectedOptions, selectOption, selectOrDeselectAll, reset }
async function getBadgeFields(response) {
try {
attendeeId.value = response.attendeeId
const fields = await useApiStore().get(true, `tickets/${response.ticketId}/badge-forms`)
printOptions.value = fields.map((field) => {
if (field.field_identifier === 'QR') {
return {
id: field.id,
name: 'code',
label: 'QR Code',
fieldIdentifier: field.field_identifier,
checked: ref(true),
disabled: true
}
} else {
return {
id: field.id,
name: field.custom_field,
label: field.custom_field,
fieldIdentifier: field.field_identifier,
checked: ref(true),
disabled: false
}
}
})
allOptions.value = printOptions.value.map((option) => {
return {
name: option.name,
id: option.id,
fieldIdentifier: option.fieldIdentifier
}
})
selectedOptions.value = allOptions.value
} catch (error) {
console.error(error)
}
}

async function displayAndPrintPDF(pdf) {
try {
const pdfBlob = pdf
const pdfUrl = URL.createObjectURL(pdfBlob);
// Create an iframe to display the PDF
const pdfIframe = document.createElement('iframe');
pdfIframe.style.display = 'none';
pdfIframe.src = pdfUrl;
// Append the iframe to the document
document.body.appendChild(pdfIframe);
// Wait for the iframe to load
await new Promise((resolve) => pdfIframe.onload = resolve);
// Print the PDF using the print function of the browser
pdfIframe.contentWindow.print();
// Clean up: remove the iframe after printing
document.body.removeChild(pdfIframe);
} catch (error) {
console.error('Error displaying or printing the PDF:', error);
}
}

async function getPDF() {
console.log(selectedOptions.value)
try {
const fieldNames = selectedOptions.value.map((option) => option.fieldIdentifier)
const payload = {
attendee_id: attendeeId.value,
list_field_show: fieldNames
}
console.log(payload)
await useApiStore().post(true, 'badge-forms/print-badge-pdf', payload, false)
.then((res) => res.blob())
.then((blob) => {
var url = window.URL.createObjectURL('a');
var a = document.createElement('a');
a.href = url;
a.download = "filename.xlsx";
document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox
a.click();
a.remove(); //after
})

// Convert raw string to Uint8Array
const uint8Array = new TextEncoder().encode(pdf);
console.log(pdf)
console.log(uint8Array)

// Create a Blob from the Uint8Array
const blob = new Blob(uint8Array, { type: 'application/pdf' });
displayAndPrintPDF(blob)

} catch (error) {
console.error(error)
}
}

return { printOptions, selectedOptions, selectOption, selectOrDeselectAll, reset, getBadgeFields, getPDF }
})
Loading

0 comments on commit 5970680

Please sign in to comment.