-
Notifications
You must be signed in to change notification settings - Fork 5
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
Qr code scanner #465
base: develop
Are you sure you want to change the base?
Qr code scanner #465
Changes from 6 commits
ab32dd3
91582c1
b503b42
d775af9
6b53c9f
8887b05
0a3fb25
550e134
588799e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
{% extends "event/base.html" %} | ||
|
||
{% block nav_links %} | ||
<li><a href="{{ url("event:dashboard") }}" class="active">Dashboard</a></li> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the class=active |
||
<li><a href="{{ url("event:change_password") }}">Change Password</a></li> | ||
{% endblock %} | ||
|
||
{% block body %} | ||
<div class="backgroundColorDashboard"> | ||
<div class="container"> | ||
<div class="section"> | ||
<div class="borderTopDiv z-depth-3"> | ||
|
||
{% if get_messages(request) %} | ||
{% for message in get_messages(request) %} | ||
<p id="submitMessage" class="banner banner{{ message.tags }}"> {{ message }} </p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Leo6Leo you need to compile the scss, run |
||
{% endfor %} | ||
{% endif %} | ||
|
||
<h1 class="formH1">QR Scanner for Sign-In</h1> | ||
{% if get_curr_sign_in_time(true) %} | ||
<p class="banner bannerinfo"> Current sign in event: <b>{{ get_curr_sign_in_time(true) }}</b> </p> | ||
{% else %} | ||
<p class="banner bannerwarning"> There is currently no event to sign in </p> | ||
{% endif %} | ||
|
||
<video id="scanner" style="width: 100%; max-height: 250px; margin: 10px auto"></video> | ||
|
||
<br/> | ||
|
||
{% if not sign_in_form %} | ||
<h4 class="errorText" style="text-align: center"> {{ hackathon_name }} is not happening now </h4> | ||
{% else %} | ||
<div id="studentInfo"> | ||
<h2 class="formH1">Student Information</h2> | ||
<form method="post"> | ||
<table> | ||
<tr> | ||
<td>Name</td> | ||
<td id="studentName"></td> | ||
</tr> | ||
<tr> | ||
<td>Email</td> | ||
<td> | ||
{{ csrf_input }} | ||
<div class="input-field"> | ||
{{ sign_in_form.email }} | ||
|
||
{% if sign_in_form.email.errors %} | ||
<span class="formFieldError"> | ||
{% for error in sign_in_form.email.errors %} | ||
{{ error }} | ||
<br /> | ||
{% endfor %} | ||
</span> | ||
{% endif %} | ||
</div> | ||
</td> | ||
</tr> | ||
</table> | ||
<button class="btn-large waves-effect waves-light colorBtn" style="margin-top: 15px" | ||
type="submit" id="signInButton"> | ||
Sign-In | ||
</button> | ||
</form> | ||
</div> | ||
{% endif %} | ||
|
||
<br/> | ||
|
||
<table> | ||
<tr> | ||
<th>Event</th> | ||
<th>Time</th> | ||
<th>Sign In Interval</th> | ||
</tr> | ||
{% for event in sign_in_times %} | ||
<tr> | ||
<td> {{ event.description }} </td> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be more intuitive to show which event is happening right now by changing the color of the column or add one more column called status, and show the emoji to indicate the status of the event. |
||
<td> {{ event.time.strftime("%H:%M, %b %d") }} </td> | ||
<td> {{ get_sign_in_interval(event.time) }} </td> | ||
</tr> | ||
{% endfor %} | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} | ||
|
||
{% block scripts %} | ||
<script src="{{ static("event/js/qr-scanner.umd.min.js") }}"></script> | ||
<script type="text/javascript"> | ||
const videoElem = document.getElementById("scanner"); | ||
let oldData = ''; | ||
|
||
$("#signInButton").click(() => { | ||
console.log(oldData.split(';')) | ||
}); | ||
|
||
const qrScanner = new QrScanner( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we able to have a button to disable the camera / QR scanner if we want to use the real scanner instead of the camera. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain this more? What is a "real scanner" I thought QR codes can only be scanned through camera/images. |
||
videoElem, | ||
(result) => { | ||
if (result) { | ||
if (result.data !== oldData) { | ||
data = result.data.split(";"); | ||
$("#studentName").text(`${data[0]} ${data[1]}`); | ||
$("#id_email").val(data[2]); | ||
$("#studentInfo").show(); | ||
$("#submitMessage").text('') | ||
oldData = result.data; | ||
} | ||
} else { | ||
oldData = ''; | ||
$("#studentInfo").hide(); | ||
} | ||
}, | ||
{ | ||
onDecodeError: (error) => {}, | ||
highlightScanRegion: true, | ||
highlightCodeOutline: true, | ||
}, | ||
); | ||
qrScanner.setInversionMode('both'); | ||
qrScanner.start(); | ||
</script> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
{% extends "event/base.html" %} | ||
|
||
{% block nav_links %} | ||
<li><a href="{{ url("event:dashboard") }}" class="active">Dashboard</a></li> | ||
<li><a href="{{ url("event:change_password") }}">Change Password</a></li> | ||
{% endblock %} | ||
|
||
{% block body %} | ||
<div class="backgroundColorDashboard"> | ||
<div class="container"> | ||
<div class="section"> | ||
<div class="borderTopDiv z-depth-3"> | ||
<h1 class="formH1">Admin Dashboard</h1> | ||
|
||
<h2 class="formH2">Administrative Actions</h2> | ||
<div class="btn-group-sm"> | ||
<a href="{{ url("event:qr-scanner") }}" class="btn-sm btn-small waves-effect waves-light colorBtn"> | ||
Scan QR Code | ||
</a> | ||
<a href="" class="btn-sm btn-small waves-effect waves-light colorBtn"> | ||
Review Applications | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: Link waiting to be updated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should hide these to all our volunteers. We don't want everyone to see our sensitive data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll disable those buttons for now (since reviews will be over at that point) and we can figure out later all the volunteer permissions. |
||
</a> | ||
<a href="" class="btn-sm btn-small waves-effect waves-light colorBtn"> | ||
View Applications | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: Link waiting to be updated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should hide these to all our volunteers. We don't want everyone to see our sensitive data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as above. |
||
</a> | ||
</div> | ||
|
||
<br/> | ||
|
||
<h2 class="formH2">Export Data to Google Sheets</h2> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should hide these to all our volunteers. We don't want everyone to see our sensitive data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, they're dsiabled for now |
||
<p>Clicking any of the below buttons will export the respective data to google sheets in this folder. Files will not be replaced, a new file will be created any time new data is exported.</p> | ||
<p>(Work In Progress)</p> | ||
<br/> | ||
<div class="btn-group-sm"> | ||
<button disabled class="btn-sm btn-small waves-effect waves-light colorBtn" | ||
type="submit">User Data</button> | ||
<button disabled class="btn-sm btn-small waves-effect waves-light colorBtn" | ||
type="submit">Application Data</button> | ||
<button disabled class="btn-sm btn-small waves-effect waves-light colorBtn" | ||
type="submit">Review Data</button> | ||
<button disabled class="btn-sm btn-small waves-effect waves-light colorBtn" | ||
type="submit">Sign-In Data</button> | ||
</div> | ||
</div> | ||
|
||
<div class="borderTopDiv z-depth-3"> | ||
<h1 class="formH1">Analytics</h1> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should hide these to all our volunteers. We don't want everyone to see our sensitive data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. smae as comment above |
||
<table> | ||
<tr> | ||
<td>Total number of sign-ups:</td> | ||
<td>345</td> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just don't forget to use the dynamic data. |
||
</tr> | ||
<tr> | ||
<td>Total number of completed applications:</td> | ||
<td>215</td> | ||
</tr> | ||
<tr> | ||
<td>Total number of completed reviews:</td> | ||
<td>0</td> | ||
</tr> | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,10 @@ <h4 class="formH2"><b>Congratulations!</b> You've been accepted into {{ hackatho | |
{% if (application.rsvp and using_rsvp) or not using_rsvp %} | ||
<p>Make sure you read the <a class="primaryText hoverLink" href="{{ participant_package_link }}" rel="noopener" target="_blank">participant package</a> for all the info regarding | ||
the event, and join our <a class="primaryText hoverLink" href="{{ chat_room_link }}" rel="noopener" target="_blank">{{ chat_room_name }}</a>. Stay tuned for more updates regarding detailed event logistics, and we hope to see you soon!</p> <br /> | ||
<div style="margin-bottom: 15px; display: flex; flex-direction: column; align-items: center"> | ||
<p>Please show the QR code below to the front desk to sign-in. .</p> | ||
<canvas id="qrcode" style="width: 150px; height: 150px; margin: 10px auto"></canvas> | ||
</div> | ||
{% endif %} | ||
<p>If you have questions, read the <a class="primaryText hoverLink" href="#faq">FAQ</a>, or feel free to contact us.</p> <br /> | ||
|
||
|
@@ -226,4 +230,15 @@ <h2 class="formH2" id="faq">Application FAQs</h2> | |
</div> | ||
</div> | ||
</div> | ||
{% endblock %} | ||
|
||
{% block scripts %} | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script> | ||
<script type="text/javascript"> | ||
var qrcode = new QRious({ | ||
element: document.getElementById("qrcode"), | ||
value: "{{ user.first_name }};{{ user.last_name }};{{ user.email }}", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is unsafe to do so. Here we are exposing user's first name, last name, and their email directly in the QR code. I would recommend we encrypt it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So for newhacks I think data was encoded the same way in the qr code. But also, I don't think this is unsafe because only the participant will have their qr code and first/last name and email is not sensitive data (in my opinion but let me know why you think it is). I don't see how people's information will be exposed in any way. Also encryption on the frontend is not super useful because ppl can find out the encryption algorithm and decrypt it. |
||
size: 150, | ||
}); | ||
</script> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Generated by Django 3.2.12 on 2023-01-12 21:58 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
("event", "0007_hss_test_users"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="UserActivity", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("sign_in", models.DateTimeField(null=True)), | ||
("lunch1", models.DateTimeField(null=True)), | ||
("dinner1", models.DateTimeField(null=True)), | ||
("breakfast2", models.DateTimeField(null=True)), | ||
("lunch2", models.DateTimeField(null=True)), | ||
( | ||
"user", | ||
models.OneToOneField( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
to=settings.AUTH_USER_MODEL, | ||
), | ||
), | ||
], | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,3 +44,12 @@ def save(self, *args, **kwargs): | |
|
||
def __str__(self): | ||
return f"{self.id} | {self.user.first_name} {self.user.last_name}" | ||
|
||
|
||
class UserActivity(models.Model): | ||
user = models.OneToOneField(User, on_delete=models.CASCADE) | ||
sign_in = models.DateTimeField(null=True) | ||
lunch1 = models.DateTimeField(null=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any ways to make this dynamic? My suggestion on this design would be: We have the table called UserActivity, and the attribute for the table will be user, created_time, event(foreign key to the table Event Arrangement), scanner(Foreign key to the table User). And another table called event, storing all the events that the admin created. And it will potentially have these attributes: event name, event id, start_time, end_time, discord_bot_notify(boolean, if it is true, discord bot will send an announcement in the channel), and more.... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I'll think about it. My main idea was because we will have a known finite number of events so in the future we can set it up just like how we set up the application model questions, but if you want to extend it to further uses I can change it. |
||
dinner1 = models.DateTimeField(null=True) | ||
breakfast2 = models.DateTimeField(null=True) | ||
lunch2 = models.DateTimeField(null=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make this as dynamic by setting it to the variable in the setting file.