Skip to content

Add functionality to use check-in app for QR code scanning with eventyay #115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: development
Choose a base branch
from

Conversation

Sak1012
Copy link
Member

@Sak1012 Sak1012 commented Jun 26, 2024

This pull request contains the initial commit addressing Issue #190 (Integrate Badges Plugin with Check-in App for QR Code Scanning) in the eventyay-tickets repository.

Overview:
In this PR, a "Register Device" button has been added to the home page. This button redirects organizers to a QR code scan interface, allowing them to register their devices similarly to the functionality of pretix-scan.

Screenshots:

  1. Home page with "Register Device" button:
    Home Page

  2. QR Code Scan Interface:
    QR Code Scan

QR Code Data Format:
The "Connect to Device" QR code in eventyay-tickets provides JSON data in the following format:

{
    "handshake_version": 1, 
    "url": "http://localhost", 
    "token": "cgakvwle23d2qxwa"
}

Progress Checklist

  • Add the required frontend button and route to scan QR code to register a device.
  • Implement logic to scan, validate, and connect to the device using the QR code from eventyay-tickets.
  • Add functions to retrieve event details.
  • Redirect to panel/select-station once the device is connected.
  • Configure support for tickets from eventyay-tickets.
  • Display a preview of the badge once the attendee is checked in.

This feature enhances the integration between the badges plugin and the check-in app, allowing event organizers to seamlessly register and manage devices using QR codes. The implementation is inspired by the functionality of pretix-scan.

Summary by Sourcery

This pull request introduces a new feature allowing event organizers to register devices via a QR code scan interface. A 'Register Device' button has been added to the home page, leading to a new route and component for device registration. Additionally, the login form has been enhanced with a server selection dropdown and corresponding error handling.

  • New Features:
    • Added a 'Register Device' button to the home page, which redirects to a QR code scan interface for device registration.
    • Implemented a new route and component for device registration using QR codes.
    • Introduced a new store for handling device registration logic and API interactions.
  • Enhancements:
    • Updated the login form to include a server selection dropdown and error handling for server selection.

Copy link

netlify bot commented Jun 26, 2024

Deploy Preview for open-event-checkin ready!

Name Link
🔨 Latest commit d2ff327
🔍 Latest deploy log https://app.netlify.com/sites/open-event-checkin/deploys/67319081ac830c00088838a9
😎 Deploy Preview https://deploy-preview-115--open-event-checkin.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@mariobehling
Copy link
Member

Thank you. You can show the functionality in the weekly meetings and we can discuss then if we should keep this in a seperate branch.

@Sak1012
Copy link
Member Author

Sak1012 commented Jul 2, 2024

I have added the required frontend component to select a server in the LoginForm Component

Screen Shots


image image image

@Sak1012
Copy link
Member Author

Sak1012 commented Jul 20, 2024

A "/eventyayevents" page has been added from where the events can be selected to perform checkin actions from a list of events the device has access to.

Screenshot 2024-07-20 at 07 30 53

This PR has multiple console.log() for testing purpose and will be removed in later commits.

@mariobehling
Copy link
Member

@sourcery-ai review

Copy link

sourcery-ai bot commented Jul 22, 2024

Reviewer's Guide by Sourcery

This pull request introduces a new feature allowing event organizers to register devices via a QR code scan interface. A 'Register Device' button has been added to the home page, and new routes and components have been implemented to support this functionality. Additionally, the login form has been enhanced with a server selection dropdown and corresponding error handling.

File-Level Changes

Files Changes
src/components/LoginForm.vue
src/router/index.js
src/components/Common/QRCamera.vue
src/stores/processDevice.js
src/components/Eventyay/EventyayEvents.vue
src/stores/eventyayEvent.js
src/components/Registration/Device/Device.vue
Introduced a new feature for device registration via QR code scanning, including UI components, routes, and state management.

Tips
  • Trigger a new Sourcery review by commenting @sourcery-ai review on the pull request.
  • Continue your discussion with Sourcery by replying directly to review comments.
  • You can change your review settings at any time by accessing your dashboard:
    • Enable or disable the Sourcery-generated pull request summary or reviewer's guide;
    • Change the review language;
  • You can always contact us if you have any questions or feedback.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Sak1012 - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Define submitForm method (link)
Here's what I looked at during the review
  • 🔴 General issues: 1 blocking issue, 9 other issues
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.


// router
const router = useRouter()

async function submitLogin() {
console.log(server.value)
if (server.value === '' || server.value === 'Select a Server') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider using a constant for the default server value

Using a constant for the default server value ('Select a Server') can help avoid potential typos and make the code easier to maintain.

Suggested change
if (server.value === '' || server.value === 'Select a Server') {
const DEFAULT_SERVER_VALUE = 'Select a Server';
if (server.value === '' || server.value === DEFAULT_SERVER_VALUE) {


try {
const api = mande(url, { headers: { Authorization: `Device ${apiToken}` } })
console.log(`/api/v1/organizers/${organizer}/events/`)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (performance): Remove console.log statements

Leaving console.log statements in production code can lead to performance issues and potential information leakage. Consider removing or replacing them with proper logging mechanisms.

const api = mande(url, { headers: { Authorization: `Device ${apiToken}` } })
console.log(`/api/v1/organizers/${organizer}/events/`)
const response = await api.get(`/api/v1/organizers/${organizer}/events/`)
console.log('Hello', response)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (performance): Remove console.log statements

Leaving console.log statements in production code can lead to performance issues and potential information leakage. Consider removing or replacing them with proper logging mechanisms.

/>
</div>
</form>
<div v-if="!loading && !events.length && !error">No events available</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider adding a retry mechanism

If no events are available, consider providing a retry mechanism or a more detailed message to guide the user.

Suggested change
<div v-if="!loading && !events.length && !error">No events available</div>
<div v-if="!loading && !events.length && !error">
No events available
<button @click="fetchEvents">Retry</button>
</div>

@Sak1012 Sak1012 force-pushed the badge-integration branch from 6834ad7 to 57f721b Compare July 22, 2024 10:58
@mariobehling
Copy link
Member

@sourcery-ai review

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Sak1012 - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Potential hard-coded secret found in 'token' field. (link)
  • Potential hard-coded secret found. (link)

Overall Comments:

  • The error handling in the authDevice function could be improved. Consider using more specific error types and providing more informative error messages to the user.
  • The hardcoded port number for localhost (:8000) in the authDevice function is not a good practice. Consider making this configurable or using a default port that doesn't require modification.
  • There's no input validation for the manual device key entry in the Device.vue component. Implement proper validation to ensure the entered key meets the required format and length.
Here's what I looked at during the review
  • 🟡 General issues: 10 issues found
  • 🔴 Security: 2 blocking issues
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.


// router
const router = useRouter()

async function submitLogin() {
console.log(server.value)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Remove console.log statements

Consider removing the console.log statements used for debugging purposes before merging the code to the main branch.

Suggested change
console.log(server.value)
const router = useRouter()
async function submitLogin() {
if (server.value === '' || server.value === 'Select a Server') {
showServerError.value = true


// router
const router = useRouter()

async function submitLogin() {
console.log(server.value)
if (server.value === '' || server.value === 'Select a Server') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use a constant for 'Select a Server'

Consider defining 'Select a Server' as a constant to avoid potential typos and make the code more maintainable.

Suggested change
if (server.value === '' || server.value === 'Select a Server') {
const SELECT_A_SERVER = 'Select a Server';
if (server.value === '' || server.value === SELECT_A_SERVER) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please define constants to compare server.value with.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, defining constants for strings like 'Select a Server' is a great practice. It helps prevent typos and makes the code more readable and maintainable. You can define the constant at the top of your script or in a separate configuration file if it's used across multiple components. Here's how you can implement it:

const SELECT_A_SERVER = 'Select a Server';

if (server.value === '' || server.value === SELECT_A_SERVER) {
  // Handle the error case
}

This way, if you ever need to change the placeholder text, you only have to update it in one place. Let me know if you need further assistance!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I have fixed it in the recent commit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to hear that you've implemented the change! Using constants for strings is definitely a good practice for maintaining clean and error-free code. If you have any more questions or need further assistance with anything else in the PR, feel free to ask. Keep up the good work!

Comment on lines 140 to 147
<StandardButton
:type="'button'"
:text="'Register-Device'"
:disabled="false"
class="btn-primary mt-6 w-full justify-center"
@click="registerDevice"
>
</StandardButton>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Button text should be a prop

Consider passing the button text as a prop to the StandardButton component for better reusability and consistency.

Suggested change
<StandardButton
:type="'button'"
:text="'Register-Device'"
:disabled="false"
class="btn-primary mt-6 w-full justify-center"
@click="registerDevice"
>
</StandardButton>
<StandardButton
:type="'button'"
:text="buttonText"
:disabled="false"
class="btn-primary mt-6 w-full justify-center"
@click="registerDevice"
/>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are passing a static string (Register-Device) to text prop, no point to use bind syntax and JS expression.

Just pass as normal HTML attribute like this:

<StandardButton text='Register-Device' ... />

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point, @hongquan! If the button text is static and won't change, using a regular HTML attribute is indeed more straightforward and cleaner. However, if there's a possibility that the button text might need to be dynamic or localized in the future, passing it as a prop could be beneficial for flexibility. It really depends on the expected use case. If you foresee any changes or need for localization, consider using a prop; otherwise, your suggestion is perfectly valid for a static text.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this was the convention followed everywhere else where StandardButton component was previously being used, I too did the same should I still change it ?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the convention in your codebase is to use the binding syntax for the text prop, even for static strings, it's generally a good idea to maintain consistency with the existing code. This can help with readability and maintainability, especially if there's a chance that the text might become dynamic or require localization in the future.

However, if you and your team decide that using a regular HTML attribute for static text is more appropriate and aligns with your coding standards, you can certainly make that change. Consistency is key, so whichever approach you choose, it would be beneficial to apply it uniformly across your project.

If you're unsure, it might be worth discussing with your team to see if there's a preference or if there's a plan to make the button text dynamic in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not convention, previous people simply don't understand VueJS well enough.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like there's a bit of a misunderstanding about the use of VueJS syntax in your codebase. If the current practice is to use the binding syntax for static strings, it might be due to a lack of understanding rather than a deliberate convention.

Given this, it could be a good opportunity to align on best practices with your team. Using a regular HTML attribute for static text is more straightforward and should be preferred unless there's a specific reason to use the binding syntax, such as future plans for dynamic content or localization.

If you decide to switch to using regular HTML attributes for static text, it might be helpful to update the existing code for consistency. This could also be a chance to document this as a coding standard for your team to follow moving forward. If you need further guidance, consider discussing this with your team or a lead developer to ensure everyone is on the same page.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how the button is defined

<script setup>
const props = defineProps({
  type: {
    type: String,
    default: 'button'
  },
  text: {
    type: String,
    default: ''
  },
  disabled: {
    type: Boolean,
    default: false
  },
  icon: {
    type: Function,
    default: () => null
  },
  iconAfter: {
    type: Function,
    default: () => null
  }
})
</script>

<template>
  <button :type="type" :disabled="disabled" class="inline-flex items-center">
    <component :is="icon" v-if="icon" :class="[text !== '' ? 'mr-1 h-5' : 'h-5']" />
    <span>{{ text }}</span>
    <component :is="iconAfter" v-if="iconAfter" :class="[text !== '' ? 'ml-1 h-5' : 'h-5']" />
  </button>
</template>

Hence I'm passing it as a prop

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that it is a prop, see my previous comment:

If you are passing a static string (Register-Device) to text prop

Being a "prop", it doesn't mean that you always have to use Vue syntax when passing a value to it.

Comment on lines 148 to 149
<div v-if="showServerError" class="mt-5">
<p class="text-center text-sm text-danger">Please select a server first</p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Error message should be configurable

Consider making the error message configurable or translatable to support multiple languages.

Suggested change
<div v-if="showServerError" class="mt-5">
<p class="text-center text-sm text-danger">Please select a server first</p>
<div v-if="showServerError" class="mt-5">
<p class="text-center text-sm text-danger">{{ errorMessage }}</p>

Comment on lines 65 to 66
if (url.includes('localhost')) {
url = `${url}:8000` // Add your desired port number here
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Avoid hardcoding port number

Consider making the port number configurable instead of hardcoding it.

Suggested change
if (url.includes('localhost')) {
url = `${url}:8000` // Add your desired port number here
const port = process.env.PORT || 8000;
if (url.includes('localhost')) {
url = `${url}:${port}`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do as sourcery-ai suggested.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, making the port number configurable is a good practice as it enhances flexibility and adaptability across different environments. By using process.env.PORT || 8000, you allow the application to dynamically adapt to the port specified in the environment variables, while still providing a default value of 8000 if none is set. This approach is particularly useful in development and deployment scenarios where the port might vary. If you need any help implementing this change or have further questions, feel free to ask!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed this in the recent commit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to hear that you've implemented the change, @Sak1012! Making the port configurable is a solid improvement. If you encounter any issues or have further questions as you continue working on this feature, feel free to reach out. Keep up the good work!


try {
const api = mande(url, { headers: { Authorization: `Device ${apiToken}` } })
console.log(`/api/v1/organizers/${organizer}/events/`)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Remove console.log statements

Consider removing the console.log statements used for debugging purposes before merging the code to the main branch.

Suggested change
console.log(`/api/v1/organizers/${organizer}/events/`)
// console.log(`/api/v1/organizers/${organizer}/events/`)

@Sak1012 Sak1012 force-pushed the badge-integration branch from 3988864 to 998dc45 Compare August 6, 2024 03:57
@Sak1012 Sak1012 force-pushed the badge-integration branch from 998dc45 to 4f382e0 Compare August 6, 2024 03:58
@mariobehling mariobehling requested a review from hongquan August 17, 2024 15:36

// router
const router = useRouter()

async function submitLogin() {
console.log(server.value)
if (server.value === '' || server.value === 'Select a Server') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please define constants to compare server.value with.

Comment on lines 140 to 147
<StandardButton
:type="'button'"
:text="'Register-Device'"
:disabled="false"
class="btn-primary mt-6 w-full justify-center"
@click="registerDevice"
>
</StandardButton>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are passing a static string (Register-Device) to text prop, no point to use bind syntax and JS expression.

Just pass as normal HTML attribute like this:

<StandardButton text='Register-Device' ... />

Comment on lines 65 to 66
if (url.includes('localhost')) {
url = `${url}:8000` // Add your desired port number here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do as sourcery-ai suggested.

This also has minor fixes and removal of some `console.log()` statements
and added env variable for local host testing
@hongquan
Copy link
Member

In this PR, every where you pass static string to Vue component, please use normal HTML instead of :prop syntax.

@Sak1012 Sak1012 changed the title Add Device Registration button and route Eventyay-tickets Integration Sep 9, 2024
@Sak1012
Copy link
Member Author

Sak1012 commented Oct 14, 2024

This PR covers most of the functionalities required to integrate the Eventyay component with Open Event Checkin. I’ve also resolved the requested changes. Kindly review this.

@Sak1012 Sak1012 requested a review from hongquan October 14, 2024 15:04
@Sak1012
Copy link
Member Author

Sak1012 commented Oct 18, 2024

In the latest commit i'm integrating Lead API and Checkin API in open-event-checkin, The Lead API is working completely fine but i'm still facing issues with the checkin api as it is not responding to the device token.

Major Changes Done to the Workflow and the tokens stored Local Storage
is now moves to  eventyayapi store
Added Feature to include notes and tags on scanned Lead
Added Option to export lead data as CSV
Made some changes to handling Checkin
@Sak1012
Copy link
Member Author

Sak1012 commented Oct 29, 2024

Added option to export scanned leads as csv

ID,Pseudonymization ID,Scanned Date,Scan Type,Device Name,Attendee Name,Email,Note,Tags
35,GYPZHJDQGV,2024-10-29,lead,Test,Jane Doe,,Meet on Friday,Anonymus; USA
36,ML7ZRUARDG,2024-10-29,lead,Test,Srivatsav,,,Photographer; USA
37,JPW8BQTCRR,2024-10-29,lead,Test,Charles Xavier,,,X-men;
ID Pseudonymization ID Scanned Date Scan Type Device Name Attendee Name Email Note Tags
35 GYPZHJDQGV 2024-10-29 lead Test Jane Doe Meet on Friday Anonymus; USA
36 ML7ZRUARDG 2024-10-29 lead Test Srivatsav India
37 JPW8BQTCRR 2024-10-29 lead Test Charles Xavier X-men

@@ -23,9 +23,11 @@ const submitForm = () => {
if (selectedEvent.value) {
const selectedEventData = events.find((event) => event.slug === selectedEvent.value)
if (selectedEventData) {
console.log('Selected Event:', selectedEventData)
console.log('Selected Role:', selectedRole)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be removed

@mariobehling mariobehling changed the title Eventyay-tickets Integration Add functionality to use check-in app for QR code scanning with eventyay Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants