Compare commits
4 commits
master
...
event-date
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f5eb90b73d | ||
![]() |
a3c89dd478 | ||
![]() |
7fc06bde11 | ||
![]() |
e28912b997 |
7 changed files with 264 additions and 21 deletions
|
@ -1,11 +1,11 @@
|
|||
import flask
|
||||
from flask import Response, render_template, redirect, request, url_for, flash
|
||||
from flask import Response, render_template, redirect, request, url_for, flash, current_app
|
||||
from flask_login import current_user, login_required
|
||||
from goathacks.admin import bp, forms
|
||||
from goathacks import db
|
||||
from goathacks.models import Event
|
||||
|
||||
import io, qrcode
|
||||
import io, qrcode, datetime
|
||||
import qrcode.image.pure
|
||||
|
||||
@bp.route("/events")
|
||||
|
@ -16,7 +16,86 @@ def list_events():
|
|||
|
||||
events = Event.query.all()
|
||||
|
||||
return render_template("events/list.html", events=events)
|
||||
form = forms.EventForm()
|
||||
|
||||
return render_template("events/list.html", events=events, form=form)
|
||||
|
||||
@bp.route("/event/<int:id>/delete")
|
||||
@login_required
|
||||
def delete_event(id):
|
||||
if not current_user.is_admin:
|
||||
return {"status": "error", "message": "Unauthorized"}
|
||||
|
||||
event = Event.query.filter_by(id=id).first()
|
||||
|
||||
if event is None:
|
||||
return {"status": "error", "message": "Invalid event ID"}
|
||||
|
||||
db.session.delete(event)
|
||||
db.session.commit()
|
||||
|
||||
return {"status": "success"}
|
||||
|
||||
@bp.route("/event/<int:id>")
|
||||
@login_required
|
||||
def event(id):
|
||||
if not current_user.is_admin:
|
||||
return {"status": "error", "message": "Unauthorized"}
|
||||
|
||||
event = Event.query.filter_by(id=id).first()
|
||||
|
||||
if event is None:
|
||||
return {"status": "error", "message": "Invalid event ID"}
|
||||
|
||||
return event.create_json()
|
||||
|
||||
@bp.route("/event/<int:id>", methods=["POST"])
|
||||
@login_required
|
||||
def update_create_event(id):
|
||||
if not current_user.is_admin:
|
||||
flash("Unauthorized")
|
||||
return redirect(url_for("dashboard.home"))
|
||||
|
||||
name = request.form.get('name')
|
||||
description = request.form.get('description')
|
||||
location = request.form.get('location')
|
||||
start_day = request.form.get('start_day')
|
||||
start_time = request.form.get('start_time')
|
||||
end_day = request.form.get('end_day')
|
||||
end_time = request.form.get('end_time')
|
||||
start = datetime.datetime.combine(datetime.date.fromisoformat(start_day),
|
||||
datetime.time.fromisoformat(start_time))
|
||||
end = datetime.datetime.combine(datetime.date.fromisoformat(end_day),
|
||||
datetime.time.fromisoformat(end_time))
|
||||
category = request.form.get("category")
|
||||
|
||||
if id == 0:
|
||||
# new event
|
||||
e = Event(
|
||||
name=name,
|
||||
description=description,
|
||||
location=location,
|
||||
start_time=start,
|
||||
category=category,
|
||||
end_time=end)
|
||||
db.session.add(e)
|
||||
db.session.commit()
|
||||
current_app.logger.info(f"{current_user} is creating a new event: {e.name}")
|
||||
else:
|
||||
e = Event.query.filter_by(id=id).first()
|
||||
if e is None:
|
||||
return {"status": "error", "message": "Invalid event ID"}
|
||||
e.name = name
|
||||
e.description = description
|
||||
e.location = location
|
||||
e.start_time = start
|
||||
e.end_time = end
|
||||
e.category=category
|
||||
db.session.commit()
|
||||
current_app.logger.info(f"{current_user} is updating an existing event: {e.name}")
|
||||
|
||||
|
||||
return redirect(url_for("admin.list_events"))
|
||||
|
||||
@bp.route("/events/events.json")
|
||||
@login_required
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, DateTimeField, SubmitField, TextAreaField
|
||||
from wtforms import StringField, DateField, TimeField, SubmitField, TextAreaField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
class EventForm(FlaskForm):
|
||||
name = StringField("Name", validators=[DataRequired()])
|
||||
description = TextAreaField("Description")
|
||||
location = StringField("Location", validators=[DataRequired()])
|
||||
start_time = DateTimeField("Start Time", validators=[DataRequired()])
|
||||
end_time = DateTimeField("End Time", validators=[DataRequired()])
|
||||
start_day = DateField("Start Day", validators=[DataRequired()])
|
||||
start_time = TimeField("Start Time", validators=[DataRequired()])
|
||||
end_day = DateField("End Day", validators=[DataRequired()])
|
||||
end_time = TimeField("End Time", validators=[DataRequired()])
|
||||
category = StringField("Category")
|
||||
submit = SubmitField("Submit")
|
||||
|
|
|
@ -21,6 +21,8 @@ class User(db.Model, UserMixin):
|
|||
phone = Column(String, nullable=True)
|
||||
gender = Column(String, nullable=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name} ({self.email})"
|
||||
def create_json_output(lis):
|
||||
hackers = []
|
||||
|
||||
|
@ -48,7 +50,7 @@ def user_loader(user_id):
|
|||
@login.unauthorized_handler
|
||||
def unauth():
|
||||
flash("Please login first")
|
||||
return redirect(url_for("registration.register"))
|
||||
return redirect(url_for("registration.login"))
|
||||
|
||||
|
||||
class PwResetRequest(db.Model):
|
||||
|
@ -73,18 +75,21 @@ class Event(db.Model):
|
|||
events = []
|
||||
|
||||
for e in lis:
|
||||
events.append({
|
||||
'id': e.id,
|
||||
'name': e.name,
|
||||
'description': e.description,
|
||||
'location': e.location,
|
||||
'start': e.start_time,
|
||||
'end': e.end_time,
|
||||
'category': e.category
|
||||
})
|
||||
events.append(e.create_json())
|
||||
|
||||
return events
|
||||
|
||||
def create_json(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"location": self.location,
|
||||
"start_time": self.start_time.isoformat(),
|
||||
"end_time": self.end_time.isoformat(),
|
||||
"category": self.category
|
||||
}
|
||||
|
||||
def get_checkins(self):
|
||||
checkins = EventCheckins.query.filter_by(event_id=self.id).all()
|
||||
|
||||
|
|
2
goathacks/static/js/jquery-3.6.3.min.js
vendored
Normal file
2
goathacks/static/js/jquery-3.6.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -19,7 +19,7 @@
|
|||
<th>Category</th>
|
||||
<th>Checked in</th>
|
||||
<th>QR Code</th>
|
||||
<th><a href="{{url_for('admin.new_event')}}">New</a></th>
|
||||
<th><a href="#editModal" data-bs-toggle="modal" data-id="0">New</a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -34,11 +34,166 @@
|
|||
<td>{{ event.get_checkins()|length }}</td>
|
||||
<td><a href='{{ url_for("admin.qrcode_event", id=event.id)
|
||||
}}'>QR Code</a></td>
|
||||
<td><a href="{{url_for('admin.edit_event', id=event.id)}}">Edit</a></td>
|
||||
<td><a href="#editModal" data-bs-toggle="modal" data-id="{{ event.id}}" >Edit</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="editModal" tabindex="-1" aria-labelledby="editModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="editModalLabel">Event</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form class="form" id="edit-form" action="/admin/events/0" role="form" method="post">
|
||||
<div class="modal-body">
|
||||
{{ form.csrf_token }}
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.name(class="form-control") }}
|
||||
{{ form.name.label() }}
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
{{ form.description(class="form-control") }}
|
||||
{{ form.description.label() }}
|
||||
</div>
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.location(class="form-control") }}
|
||||
{{ form.location.label() }}
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
{{ form.category(class="form-control") }}
|
||||
{{ form.category.label() }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.start_day(class="form-control") }}
|
||||
{{ form.start_day.label() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.start_time(class="form-control") }}
|
||||
{{ form.start_time.label() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.end_day(class="form-control") }}
|
||||
{{ form.end_day.label() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.end_time(class="form-control") }}
|
||||
{{ form.end_time.label() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-id="0" id="delete">Delete</button>
|
||||
<button type="submit" class="btn btn-primary" id="edit-save">Save changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/jquery-3.6.3.min.js') }}" charset="utf-8"></script>
|
||||
|
||||
<script charset="utf-8">
|
||||
const editButton = document.getElementById("edit-save")
|
||||
|
||||
$('#delete').on("click", (event) => {
|
||||
if (window.confirm("Delete this event?")) {
|
||||
console.log("Got OK")
|
||||
deleteButton = document.getElementById("delete")
|
||||
id = deleteButton.dataset.id
|
||||
$.get(`/admin/event/${id}/delete`, (data) => {
|
||||
if (data.status == "error") {
|
||||
window.alert(`Error: ${data.message}`)
|
||||
} else {
|
||||
window.alert("Success")
|
||||
}
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
$('#editModal').on('show.bs.modal', function(event) {
|
||||
var modal = $(this)
|
||||
modal.find('#name').val('')
|
||||
modal.find('#location').val('')
|
||||
modal.find('#description').val('')
|
||||
modal.find('#start_day').val('')
|
||||
modal.find('#start_time').val('')
|
||||
modal.find('#end_day').val('')
|
||||
modal.find('#end_time').val('')
|
||||
|
||||
var button = $(event.relatedTarget)
|
||||
var name,description,loc,start_time,start_day,end_time,end_day
|
||||
id = button.data('id')
|
||||
|
||||
saveButton = document.getElementById("edit-save")
|
||||
saveButton.dataset.id = id
|
||||
|
||||
deleteButton = document.getElementById("delete")
|
||||
deleteButton.dataset.id = id
|
||||
|
||||
editForm = document.getElementById("edit-form")
|
||||
editForm.action = "/admin/event/" + id
|
||||
|
||||
if (id) {
|
||||
$.get(`/admin/event/${id}`, (data) => {
|
||||
|
||||
if (data.status == "error") {
|
||||
// This is a new event, do nothing!
|
||||
} else {
|
||||
name = data.name,
|
||||
description = data.description,
|
||||
loc = data.location,
|
||||
category = data.category
|
||||
|
||||
start = new Date(data.start_time)
|
||||
|
||||
var day = ("0" + start.getDate()).slice(-2);
|
||||
var month = ("0" + (start.getMonth() + 1)).slice(-2);
|
||||
|
||||
start_day = start.getFullYear()+"-"+(month)+"-"+(day);
|
||||
start_time = `${start.getHours()}:${padTwoDigits(start.getMinutes())}`
|
||||
end = new Date(data.end_time)
|
||||
|
||||
var day = ("0" + end.getDate()).slice(-2);
|
||||
var month = ("0" + (end.getMonth() + 1)).slice(-2);
|
||||
|
||||
end_day = end.getFullYear()+"-"+(month)+"-"+(day);
|
||||
end_time = `${end.getHours()}:${padTwoDigits(end.getMinutes())}`
|
||||
}
|
||||
|
||||
modal.find('#name').val(name)
|
||||
modal.find('#location').val(loc)
|
||||
modal.find('#description').val(description)
|
||||
modal.find('#start_day').val(start_day)
|
||||
modal.find('#start_time').val(start_time)
|
||||
modal.find('#end_day').val(end_day)
|
||||
modal.find('#end_time').val(end_time)
|
||||
modal.find('#category').val(category)
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
function padTwoDigits(num) {
|
||||
return num.toString().padStart(2, '0')
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8d8a691aad1cea4037bb9d33ddf7230d8d272597
|
||||
Subproject commit e0fb69c0be54c6cce7391ccb86a9bf14b80f432b
|
|
@ -9,7 +9,7 @@ Flask-Login==0.6.2
|
|||
Flask-Migrate==4.0.0
|
||||
Flask-SQLAlchemy==3.0.2
|
||||
Flask-WTF==1.0.1
|
||||
greenlet==2.0.1
|
||||
greenlet
|
||||
itsdangerous==2.1.2
|
||||
Jinja2==3.1.2
|
||||
Mako==1.2.4
|
||||
|
@ -19,7 +19,7 @@ psycopg2==2.9.5
|
|||
pynvim==0.4.3
|
||||
python-dotenv==0.21.0
|
||||
SQLAlchemy==1.4.44
|
||||
uWSGI==2.0.21
|
||||
uWSGI
|
||||
Werkzeug==2.2.2
|
||||
WTForms==3.0.1
|
||||
ulid
|
||||
|
|
Loading…
Add table
Reference in a new issue