Skip to content

Commit

Permalink
Merge pull request #33 from wpi-acm/event-date-time-fields
Browse files Browse the repository at this point in the history
Event Modals & Split date/time fields
  • Loading branch information
Muirrum authored Jun 5, 2024
2 parents 3a41dc6 + f5eb90b commit d0240d1
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 21 deletions.
85 changes: 82 additions & 3 deletions goathacks/admin/events.py
Original file line number Diff line number Diff line change
@@ -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")
Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions goathacks/admin/forms.py
Original file line number Diff line number Diff line change
@@ -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")
25 changes: 15 additions & 10 deletions goathacks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []

Expand Down Expand Up @@ -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):
Expand All @@ -73,17 +75,20 @@ def create_json_output(lis):
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()
Expand Down
2 changes: 2 additions & 0 deletions goathacks/static/js/jquery-3.6.3.min.js

Large diffs are not rendered by default.

159 changes: 157 additions & 2 deletions goathacks/templates/events/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ <h2>Events</h2>
<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>
Expand All @@ -34,11 +34,166 @@ <h2>Events</h2>
<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 %}
2 changes: 1 addition & 1 deletion goathacks/templates/home
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit d0240d1

Please sign in to comment.