Skip to content

Commit

Permalink
pdf api in progress (fossasia#92)
Browse files Browse the repository at this point in the history
* Add Home, Room Check-in

* fixed codacy

* clear netlify build

* Update SearchAttendee.vue

* Update ScanSearch

* Fixed navabr

* Update BaseTemplate.vue

* Removed bottom navbar and updated dropdown menu

* Minor fixes

* Added checklist to printModal and simplified router

* Name changes

* Fixed passwordModal and removed password requirement for stats

* Switched to template refs

* minor fixes

* Rearranged and renamed

* Fix codacy issues

* Changed casing

* Fix fossasia#31 Added dropdown list that allows user to choose which details to show on search

* Fixed format

* Fix codacy

* Minor fixes and renaming

* Minor fixes and moved some code to inline

* Fix fossasia#41 and codacy

* fix codacy

* Simplified code

* fix fossasia#48 created standard button component and replaced some buttons

* fix format

* Converted all buttons to standard component

* fixed format

* fix codacy

* Fix fossasia#40 standardised all p-6 except pages with scanners, optimised search function for mobile

* changed prop name

* removed activated classes

* Minor UI fixes

* fix fossasia#52 clicking print on search attendee now opens the print modal and logs name of card

* fix fossasia#51 new layout for print modal

* changed to margin

* removed grow flex

* minor fixes

* fix fossasia#50 created success notification that shows on print

* removed redundant code

* fix  margin of print modal

* changed naming

* switched to camel case, moved some functions to inline

* minor changes

* changed some refs to computed

* fix fossasia#49 fossasia#46 ported everything to stores

* fix codacy

* fix fossasia#59 fossasia#53 search and logout attached to respective APIs

* fix netlify

* fix netlify

* fix netlify

* fix codacy

* fix codacy

* fix codacy

* fix build

* fix codacy

* fix codacy

* fix fossasia#61 implemented API for checking in attendees in registration via scan or search

* fixed error

* added dayjs

* remove moment

* fix comments

* fix comments

* fix comment

* fix fossasia#68 implemented better error handling for logout function

* Update auth.js

* Update auth.js

* fix fossasia#73 navbar dropdown fixed for small screen

* fix comment

* fix fossasia#82 fossasia#75  new routing to both stats

* fix codacy

* pdf api in progress

* fix scan not working

---------

Co-authored-by: cweitat <[email protected]>
Co-authored-by: lizardon <[email protected]>
  • Loading branch information
3 people committed Aug 15, 2023
1 parent 575f5ff commit 17055a5
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 47 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@heroicons/vue": "^2.0.18",
"mande": "^2.0.6",
"pinia": "^2.1.3",
"print-js": "^1.6.0",
"vue": "^3.3.4",
"vue-qrcode-reader": "3.1.0-vue3-compatibility.2",
"vue-router": "^4.2.2"
Expand Down
13 changes: 9 additions & 4 deletions src/components/Modals/PrintModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,27 @@ const printingText = ref(false)
const titleText = 'Select items to print'
function printDelay(delayHideModal, delayPrint) {
setTimeout(() => printModalStore.showPrintModal.value = false, delayHideModal)
setTimeout(() => printModalStore.showPrintModal = false, delayHideModal)
setTimeout(() => {
notificationStore.addNotification(
['Successfully printed!', 'Please collect your ticket.'],
'success'
)
printModalStore.reset()
disableButton.value = false
printingText.value = false
}, delayPrint)
}
function print() {
printModalStore.printOptions.forEach((element) => (element.disabled = true))
printingText.value = true
disableButton.value = true
const stringFields = printModalStore.selectedOptions
.map((element) => element.fieldIdentifier)
.join(',')
printModalStore.getPDF()
printModalStore.getPDF(stringFields)
printDelay(3000, 3200)
}
</script>
Expand Down Expand Up @@ -86,8 +91,8 @@ function print() {
:class="[
disableButton
? 'cursor-not-allowed opacity-20'
: 'hover:bg-blue-500 hover:border-blue-500 hover:text-white',
'text-blue-600 border border-blue-600 ml-6'
: 'hover:opacity-75',
'text-primary border border-primary ml-6'
]"
@click="printModalStore.selectOrDeselectAll"
/>
Expand Down
6 changes: 4 additions & 2 deletions src/components/Registration/Kiosk/ScannerCamera.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const printModalStore = usePrintModalStore()
// get scanner type from vue router params
const route = useRoute()
const scannerType = route.params.scannerType
const stationId = route.params.stationId
const camera = ref('front')
Expand All @@ -28,8 +29,9 @@ async function logErrors(promise) {
}
async function decodeQR() {
await scannerStore.checkInAttendeeScanner().then(() => {
printModalStore.showPrintModal.value = true})
await scannerStore.checkInAttendeeScanner(stationId).then(() => {
printModalStore.showPrintModal = true
})
}
</script>

Expand Down
6 changes: 4 additions & 2 deletions src/components/Registration/Manual/ScanSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const notificationStore = useNotificationStore()
// get scanner type from vue router params
const route = useRoute()
const scannerType = route.params.scannerType
const eventId = route.params.eventId
const stationId = route.params.stationId
const camera = ref('front')
Expand All @@ -30,7 +30,9 @@ async function logErrors(promise) {
}
async function decodeQR() {
await scannerStore.checkInAttendeeScanner().then(() => printModalStore.value = true).catch(() => notificationStore.addNotification({ type: 'error', message: 'Attendee not found' }))
await scannerStore.checkInAttendeeScanner(stationId)
.then(() => printModalStore.showPrintModal = true)
.catch(() => notificationStore.addNotification({ type: 'error', message: 'Attendee not found' }))
}
</script>

Expand Down
7 changes: 4 additions & 3 deletions src/components/Registration/Manual/SearchAttendee.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ async function checkin(id) {
} else console.log('check in failed')
}
function printBadge(id) {
printModalStore.ticketId = id
function printBadge(ticketId, attendeeId) {
printModalStore.ticketId = ticketId
printModalStore.attendeeId = attendeeId
printModalStore.getBadgeFields()
printModalStore.showPrintModal = true
}
Expand Down Expand Up @@ -270,7 +271,7 @@ function printBadge(id) {
:text="'Print'"
:icon="PrinterIcon"
class="btn-info"
@click="printBadge(attendee.ticketId)"
@click="printBadge(attendee.ticketId, attendee.id)"
/>
</div>
</div>
Expand Down
81 changes: 56 additions & 25 deletions src/stores/printModal.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import print from 'print-js'
import { useApiStore } from '@/stores/api'

export const usePrintModalStore = defineStore('printModal', () => {
const showPrintModal = ref(false)
const attendeeId = ref(null)
const ticketId = ref(null)
//for user interaction
const printOptions = ref([])
Expand Down Expand Up @@ -39,7 +41,10 @@ export const usePrintModalStore = defineStore('printModal', () => {
}

function reset() {
selectedOptions.value = allOptions.value
attendeeId.value = null
ticketId.value = null
selectedOptions.value = []
allOptions.value = []
printOptions.value.forEach((option) => {
if (option.name !== 'code') {
option.disabled = false
Expand All @@ -51,27 +56,32 @@ export const usePrintModalStore = defineStore('printModal', () => {
async function getBadgeFields() {
try {
const fields = await useApiStore().get(true, `tickets/${ticketId.value}/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
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
}
}
} else {
return {
id: field.id,
name: field.custom_field,
label: field.custom_field,
fieldIdentifier: field.field_identifier,
checked: ref(true),
disabled: false
}
}
})
})
// move QR to front of array
const QRField = printOptions.value.splice(printOptions.value.indexOf((element) => element.field_identifier === 'QR'), 1)[0]
printOptions.value.unshift(QRField)

allOptions.value = printOptions.value.map((option) => {
return {
name: option.name,
Expand All @@ -85,10 +95,31 @@ export const usePrintModalStore = defineStore('printModal', () => {
}
}

async function getPDF() {
// get pdf api here
// return pdf url
function printPDF(blob) {
var reader = new FileReader()
reader.onload = function () {
//Remove the data:application/pdf;base64,
printJS({
printable: reader.result.substring(28),
type: 'pdf',
base64: true
})
}
reader.readAsDataURL(blob)
}

async function getPDF(fields) {
try {
console.log(fields, attendeeId.value)
const url = await useApiStore().get(true, `badge-forms/print-badge-pdf?attendee_id=${attendeeId.value}&list_field_show=${fields}`)
const pdf = await useApiStore().get(true, url.task_url.substring(4))
const link = new Blob([pdf.result.download_url], { type: 'application/pdf' })
//print
printPDF(link)
} catch (error) {
console.error(error)
}
}

return { showPrintModal, ticketId, printOptions, selectedOptions, selectOption, selectOrDeselectAll, reset, getBadgeFields, getPDF }
return { showPrintModal, ticketId, attendeeId, printOptions, selectedOptions, selectOption, selectOrDeselectAll, reset, getBadgeFields, getPDF }
})
10 changes: 8 additions & 2 deletions src/stores/scanner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ref } from 'vue'
import { defineStore } from 'pinia'
import { useSearchAttendeeStore } from '@/stores/searchAttendee'
import { usePrintModalStore } from '@/stores/printModal'
import { useApiStore } from '@/stores/api'

export const useScannerStore = defineStore('scanner', () => {
const QRCodeValue = ref('')
Expand Down Expand Up @@ -46,10 +48,14 @@ export const useScannerStore = defineStore('scanner', () => {
return match ? parseInt(match[1], 10) : null
}

async function checkInAttendeeScanner() {
async function checkInAttendeeScanner(stationId) {
if (isValidQRCode(stringModifier(QRCodeValue.value))) {
const checkedIn = await useSearchAttendeeStore().checkInAttendee(extractId(QRCodeValue.value)) // Patch API to check-in
const checkedIn = await useSearchAttendeeStore().checkInAttendee(extractId(QRCodeValue.value), stationId) // Patch API to check-in
if (checkedIn) {
const ticketId = await useApiStore().get(true, `attendees/${extractId(QRCodeValue.value)}`)
usePrintModalStore().ticketId = ticketId.data.attributes['ticket-id']
usePrintModalStore().attendeeId = extractId(QRCodeValue.value)
usePrintModalStore().getBadgeFields()
return true
} else {
console.log('Error: Check in failed')
Expand Down
14 changes: 5 additions & 9 deletions src/stores/searchAttendee.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,24 @@ export const useSearchAttendeeStore = defineStore('searchAttendee', () => {
ticketId: attendee.ticket_id,
checkedIn: ref(attendee.is_registered),
info: {
organisation: attendee.company
attendee
}
}))
console.log(people.value)
}

function clearAttendees() {
people.value = []
}

async function checkInAttendee(attendeeId, stationId, eventId) {
async function checkInAttendee(attendeeId, stationId) {
try {
const stations = await useApiStore().get(true, `events/${eventId}/stations`)
const station = stations.data.find((station) => station.id == stationId)
const payload = {
data: {
relationships: {
station: {
data: {
type: station.type,
type: 'station',
id: stationId + ''
}
},
Expand All @@ -71,10 +70,7 @@ export const useSearchAttendeeStore = defineStore('searchAttendee', () => {
console.log('register success:', attendeeId, checkInRes)
return true
} catch (error) {
const errors = error.originalError.body.errors
if (errors.find((error) => error.detail === 'Attendee already registered.')) {
throw new Error('Already checked in')
}
console.error(error)
}
}

Expand Down

0 comments on commit 17055a5

Please sign in to comment.