Prepare administration-index
This page was until new pretty useless. It has now been fitted with links to the administrative tools, along with an explanation on what to find there.
- Author
- Maarten 'Vngngdn' Vangeneugden
- Date
- April 15, 2018, 7:10 p.m.
- Hash
- 2892e32d0763f86489fac9a05c7162e31f26f2f0
- Parent
- 361af8bc2b9bd70b6b9a553b0cc16307830da437
- Modified files
- administration/templates/administration/index.djhtml
- administration/views.py
- courses/templates/courses/index.djhtml
- static/css/header.scss
administration/templates/administration/index.djhtml ¶
8 additions and 0 deletions.
View changes Hide changes
1 |
1 |
{% load i18n %} |
2 |
2 |
{% load humanize %} |
3 |
3 |
{% load joeni_org %} |
4 |
4 |
|
5 |
5 |
{% block title %} |
6 |
6 |
{% trans "Administration" %} | {{ block.super }} |
7 |
7 |
{% endblock %} |
8 |
8 |
|
9 |
9 |
{% block main %} |
10 |
10 |
<h1>{% trans "Administration" %}</h1> |
11 |
11 |
<p> |
12 |
12 |
{% blocktrans %} |
13 |
13 |
Welcome to the administration website of Hasselt University. Here, |
14 |
14 |
you can find all links related to the university's services, |
15 |
15 |
events, messages, and so on. |
16 |
16 |
{% endblocktrans %} |
17 |
17 |
</p> |
18 |
18 |
|
+ |
19 |
{% for link, title, description in links %} |
+ |
20 |
<a class="flex-items uhasselt" href="{% url link %}"> |
+ |
21 |
<span style="font-weight:bold;">{{ title }}</span><br /> |
+ |
22 |
{{ description|safe }} |
+ |
23 |
</a> |
+ |
24 |
{% endfor %} |
+ |
25 |
</div> |
+ |
26 |
|
19 |
27 |
<h2>{% trans "Education department bulletin board" %}</h2> |
20 |
28 |
{% for message in education_dept_messages %} |
21 |
29 |
<h3>{{message.title}}</h3> |
22 |
30 |
<time datetime="{{ message.date|date:'Y-m-d' }}"> |
23 |
31 |
{{ message.date|naturaltime }} |
24 |
32 |
</time> |
25 |
33 |
<p>{{message.text|org}}</p> |
26 |
34 |
{% empty %} |
27 |
35 |
<p>{% trans "There are no messages available." %}</p> |
28 |
36 |
{% endfor %} |
29 |
37 |
|
30 |
38 |
<h2>{% trans "Important telephone numbers and contact services" %}</h2> |
31 |
39 |
<dl> |
32 |
40 |
<dt>{% trans "Student secretary during working hours" %}</dt> |
33 |
41 |
<dd><a href="tel:+3211268100">(+32)11 26 81 00</a></dd> |
34 |
42 |
<dt>{% trans "Student police | District office" %}</dt> |
35 |
43 |
<dd><a href="tel:+3211268115">(+32)11 26 81 15</a></dd> |
36 |
44 |
<dt>{% trans "Student police | District service" %}</dt> |
37 |
45 |
<dd><a href="tel:+3211323300">(+32)11 32 33 00</a></dd> |
38 |
46 |
</dl> |
39 |
47 |
{% comment %} |
40 |
48 |
Psychosociale opvang binnen de kantooruren |
41 |
49 |
Studentenpsycholoog:studentenpsycholoog@uhasselt.be - tel.:011 26 90 48 |
42 |
50 |
Maatschappelijk assistent: Liesbeth Huber |
43 |
51 |
Logistieke vragen buiten de kantooruren |
44 |
52 |
Dienst MAT Diepenbeek: 0475 94 30 02 |
45 |
53 |
Dienst MAT Hasselt: 0493 59 38 33 |
46 |
54 |
Studentenpolitie |
47 |
55 |
Wijkkantoor: 011 26 81 15 |
48 |
56 |
Wijkdienst: 011 32 33 00 |
49 |
57 |
0499 59 57 28 |
50 |
58 |
Tele-Onthaal (24u/24u) |
51 |
59 |
106 |
52 |
60 |
#TODO |
53 |
61 |
{% endcomment %} |
54 |
62 |
|
55 |
63 |
{% endblock main %} |
56 |
64 |
administration/views.py ¶
25 additions and 0 deletions.
View changes Hide changes
1 |
1 |
from collections import OrderedDict |
2 |
2 |
from django.http import HttpResponseRedirect |
3 |
3 |
import datetime |
4 |
4 |
from django.urls import reverse # Why? |
5 |
5 |
from django.utils.translation import gettext as _ |
6 |
6 |
from .models import * |
7 |
7 |
from .forms import UserDataForm |
8 |
8 |
from .new_roster import create_roster_rows |
9 |
9 |
import administration |
10 |
10 |
from django.contrib.auth.decorators import login_required |
11 |
11 |
from django.contrib.auth import authenticate |
12 |
12 |
|
13 |
13 |
@login_required |
14 |
14 |
def roster(request, begin=None, end=None): |
15 |
15 |
"""Collects and renders the data that has to be displayed in the roster. |
16 |
16 |
|
17 |
17 |
The begin and end date can be specified. Only roster points in that range |
18 |
18 |
will be included in the response. If no begin and end are specified, it will |
19 |
19 |
take the current week as begin and end point. If it's |
20 |
20 |
weekend, it will take next week.""" |
21 |
21 |
|
22 |
22 |
# TODO Handle given begin and end |
23 |
23 |
context = dict() |
24 |
24 |
#context = {'money' : update_balance(None)} |
25 |
25 |
template = "administration/roster.djhtml" |
26 |
26 |
|
27 |
27 |
if begin is None or end is None: |
28 |
28 |
today = datetime.date.today() |
29 |
29 |
if today.isoweekday() in {6,7}: # Weekend |
30 |
30 |
begin = today + datetime.timedelta(days=8-today.isoweekday()) |
31 |
31 |
end = today + datetime.timedelta(days=13-today.isoweekday()) |
32 |
32 |
else: # Same week |
33 |
33 |
begin = today - datetime.timedelta(days=today.weekday()) |
34 |
34 |
end = today + datetime.timedelta(days=5-today.isoweekday()) |
35 |
35 |
else: # Changing regexes to date objects |
36 |
36 |
b = begin.split("-") |
37 |
37 |
e = end.split("-") |
38 |
38 |
begin = datetime.datetime(int(b[2]),int(b[1]),int(b[0])) |
39 |
39 |
end = datetime.datetime(int(e[2]),int(e[1]),int(e[0])) |
40 |
40 |
|
41 |
41 |
context['begin'] = begin |
42 |
42 |
context['end'] = end |
43 |
43 |
|
44 |
44 |
context['prev_begin'] = (begin - datetime.timedelta(days=7)).strftime("%d-%m-%Y") |
45 |
45 |
context['prev_end'] = (begin - datetime.timedelta(days=2)).strftime("%d-%m-%Y") |
46 |
46 |
context['next_begin'] = (end + datetime.timedelta(days=2)).strftime("%d-%m-%Y") |
47 |
47 |
context['next_end'] = (end + datetime.timedelta(days=7)).strftime("%d-%m-%Y") |
48 |
48 |
|
49 |
49 |
days = [begin] |
50 |
50 |
while (end-days[-1]).days != 0: |
51 |
51 |
# Human translation: Keep adding days until the last day in the array of |
52 |
52 |
# days is the same day as the last day the user wants to see the roster for. |
53 |
53 |
days.append(days[-1] + datetime.timedelta(days=1)) |
54 |
54 |
context['days'] = days |
55 |
55 |
|
56 |
56 |
# Collecting events |
57 |
57 |
course_events = CourseEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end).order_by("begin_time") |
58 |
58 |
#university_events = UniversityEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
59 |
59 |
#study_events = StudyEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
60 |
60 |
#events = Event.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
61 |
61 |
conflicts, table_code = create_roster_rows(course_events) |
62 |
62 |
|
63 |
63 |
context['time_blocks'] = table_code |
64 |
64 |
context['conflicts'] = conflicts |
65 |
65 |
#print(time_blocks) |
66 |
66 |
return render(request, template, context) |
67 |
67 |
# TODO Finish! |
68 |
68 |
|
69 |
69 |
def roster_ics(request, user_slug): |
70 |
70 |
template = "administration/roster.ics" |
71 |
71 |
context = dict() |
72 |
72 |
context['events'] = CourseEvent.objects.all() # FIXME: Filter to personal calendar items! |
73 |
73 |
return render(request, template, context) |
74 |
74 |
|
75 |
75 |
def index(request): |
76 |
76 |
template = "administration/index.djhtml" |
77 |
77 |
#context = {'money': update_balance(None)} |
78 |
78 |
return render(request, template, context) |
+ |
79 |
context['links'] = [ |
+ |
80 |
("administration-settings", |
+ |
81 |
_("Personal settings"), |
+ |
82 |
_("Edit your personal information, billing address, home address, and so on.")), |
+ |
83 |
("administration-curriculum", |
+ |
84 |
_("Curricula"), |
+ |
85 |
_("View all information related to your curricula, including exam results.<br />" |
+ |
86 |
"You can also change your current curriculum here, or request a change.")), |
+ |
87 |
("administration-forms", |
+ |
88 |
_("Forms"), |
+ |
89 |
_("All forms for special services can be found on this page.")), |
+ |
90 |
("administration-rooms", |
+ |
91 |
_("Rooms"), |
+ |
92 |
_("Room occupancy, free rooms, properties, ... <br />" |
+ |
93 |
"All this and much more is available on this page.")), |
+ |
94 |
("administration-roster", |
+ |
95 |
_("Personal roster"), |
+ |
96 |
_("Everything about your roster and events at Hasselt University is available here.")), |
+ |
97 |
("administration-bulletin-board", |
+ |
98 |
_("Bulletin board"), |
+ |
99 |
_("From time to time, UHasselt publishes announcements regarding changes, events, ..." |
+ |
100 |
"<br />All publications are neatly organized here for easy reference.")), |
+ |
101 |
] |
+ |
102 |
|
+ |
103 |
return render(request, template, context) |
79 |
104 |
|
80 |
105 |
pass |
81 |
106 |
|
82 |
107 |
def pre_registration(request): |
83 |
108 |
user_data_form = UserDataForm() |
84 |
109 |
template = "administration/pre_registration.djhtml" |
85 |
110 |
context = dict() |
86 |
111 |
|
87 |
112 |
if request.method == 'POST': |
88 |
113 |
user_data_form = UserDataForm(request.POST) |
89 |
114 |
context['user_data_form'] = user_data_form |
90 |
115 |
if user_data_form.is_valid(): |
91 |
116 |
user_data_form.save() |
92 |
117 |
context['messsage'] = _("Your registration has been completed. You will receive an e-mail shortly.") |
93 |
118 |
else: |
94 |
119 |
context['messsage'] = _("The data you supplied had errors. Please review your submission.") |
95 |
120 |
else: |
96 |
121 |
context['user_data_form'] = UserDataForm(instance = user_data_form) |
97 |
122 |
|
98 |
123 |
return render(request, template, context) |
99 |
124 |
pass |
100 |
125 |
|
101 |
126 |
@login_required |
102 |
127 |
def settings(request): |
103 |
128 |
user_data = UserData.objects.get(user=request.user) |
104 |
129 |
user_data_form = UserDataForm(instance = user_data) |
105 |
130 |
template = "administration/settings.djhtml" |
106 |
131 |
context = dict() |
107 |
132 |
#context = {'money' : update_balance(None)} |
108 |
133 |
|
109 |
134 |
if request.method == 'POST': |
110 |
135 |
user_data_form = UserDataForm(request.POST, instance = user_data) |
111 |
136 |
context['user_data_form'] = user_data_form |
112 |
137 |
if user_data_form.is_valid(): |
113 |
138 |
user_data_form.save() |
114 |
139 |
context['messsage'] = _("Your settings were successfully updated.") |
115 |
140 |
else: |
116 |
141 |
context['messsage'] = _("The data you supplied had errors. Please review your submission.") |
117 |
142 |
else: |
118 |
143 |
context['user_data_form'] = UserDataForm(instance = user_data) |
119 |
144 |
|
120 |
145 |
return render(request, template, context) |
121 |
146 |
|
122 |
147 |
@login_required |
123 |
148 |
def bulletin_board(request): |
124 |
149 |
context = dict() |
125 |
150 |
#context = {'money' : update_balance(None)} |
126 |
151 |
context['exam_commission_decisions'] = ExamCommissionDecision.objects.filter(user=request.user) |
127 |
152 |
context['education_department_messages'] = EducationDepartmentMessages.objects.all() |
128 |
153 |
for item in context['education_department_messages']: |
129 |
154 |
print(item.text) |
130 |
155 |
template = "administration/bulletin_board.djhtml" |
131 |
156 |
return render(request, template, context) |
132 |
157 |
|
133 |
158 |
def jobs(request): |
134 |
159 |
context = dict() |
135 |
160 |
#context = {'money' : update_balance(None)} |
136 |
161 |
template = "administration/jobs.djhtml" |
137 |
162 |
#@context['decisions'] = ExamCommissionDecision.objects.filter(user=request.user) |
138 |
163 |
return render(request, template, context) |
139 |
164 |
|
140 |
165 |
|
141 |
166 |
@login_required |
142 |
167 |
def curriculum(request): |
143 |
168 |
context = dict() |
144 |
169 |
#context = {'money' : update_balance(None)} |
145 |
170 |
template = "administration/curriculum.djhtml" |
146 |
171 |
context['curricula'] = Curriculum.objects.filter(student=request.user) |
147 |
172 |
for item in context['curricula']: |
148 |
173 |
for co in item.course_programmes_results(): |
149 |
174 |
print(co) |
150 |
175 |
return render(request, template, context) |
151 |
176 |
|
152 |
177 |
def result(request): |
153 |
178 |
return render(request, template, context) |
154 |
179 |
|
155 |
180 |
@login_required |
156 |
181 |
def results(request): |
157 |
182 |
results = CourseResult.objects.filter(student=request.user) |
158 |
183 |
template = "administration/results.djhtml" |
159 |
184 |
# TODO |
160 |
185 |
return render(request, template, context) |
161 |
186 |
|
162 |
187 |
def forms(request): |
163 |
188 |
context = dict() |
164 |
189 |
#context = {'money' : update_balance(None)} |
165 |
190 |
template = "administration/forms.djhtml" |
166 |
191 |
return render(request, template, context) |
167 |
192 |
|
168 |
193 |
def user(request, slug_name): |
169 |
194 |
pass |
170 |
195 |
|
171 |
196 |
def rooms(request): |
172 |
197 |
context = dict() |
173 |
198 |
#context = {'money' : update_balance(None)} |
174 |
199 |
context['rooms'] = Room.objects.all() |
175 |
200 |
context['room_reservations'] = RoomReservation.objects.all() |
176 |
201 |
context['course_events'] = CourseEvent.objects.all() |
177 |
202 |
context['blocks'] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'] |
178 |
203 |
|
179 |
204 |
# Collecting all rooms that are free for at least one two hours from now |
180 |
205 |
now = datetime.datetime.now(datetime.timezone.utc) |
181 |
206 |
end = now + datetime.timedelta(hours=2) |
182 |
207 |
free_rooms = dict() |
183 |
208 |
for room in context['rooms']: |
184 |
209 |
if room.reservation_possible(now, end): |
185 |
210 |
event = room.next_event(end) |
186 |
211 |
reservation = room.next_reservation(end) |
187 |
212 |
if event is None and reservation is None: |
188 |
213 |
free_rooms[room] = None |
189 |
214 |
elif reservation is not None: |
190 |
215 |
free_rooms[room] = event.begin_time |
191 |
216 |
elif event is not None: |
192 |
217 |
free_rooms[room] = reservation.begin_time |
193 |
218 |
elif event.begin_time < reservation.begin_time: |
194 |
219 |
free_rooms[room] = event.begin_time |
195 |
220 |
else: |
196 |
221 |
free_rooms[room] = reservation.begin_time |
197 |
222 |
context['free_rooms'] = free_rooms |
198 |
223 |
|
199 |
224 |
template = "administration/rooms.djhtml" |
200 |
225 |
return render(request, template, context) |
201 |
226 |
|
202 |
227 |
def room_detail(request, room): |
203 |
228 |
template = "administration/room_detail.djhtml" |
204 |
229 |
context = dict() |
205 |
230 |
#context = {'money' : update_balance(None)} |
206 |
231 |
room = Room.objects.get(name=room) |
207 |
232 |
context['room'] = room |
208 |
233 |
context['reservations'] = RoomReservation.objects.filter(room=room).filter(begin_time__gte=datetime.datetime.now()) |
209 |
234 |
context['course_events'] = CourseEvent.objects.filter(room=room).filter(begin_time__gte=datetime.datetime.now()) |
210 |
235 |
# Building the room occupancy of today: |
211 |
236 |
today = datetime.date.today() |
212 |
237 |
if today.isoweekday() in {6,7}: # Weekend |
213 |
238 |
today = today + datetime.timedelta(days=8-today.isoweekday()) |
214 |
239 |
|
215 |
240 |
context['days'] = [today] |
216 |
241 |
|
217 |
242 |
# Collecting events |
218 |
243 |
course_events = CourseEvent.objects.filter(room=room).filter(begin_time__date=today) |
219 |
244 |
print(course_events) |
220 |
245 |
#university_events = UniversityEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
221 |
246 |
#study_events = StudyEvent.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
222 |
247 |
#events = Event.objects.filter(begin_time__gte=begin).filter(end_time__lte=end) |
223 |
248 |
|
224 |
249 |
conflicts, table_code = create_roster_rows(course_events) |
225 |
250 |
context['time_blocks'] = table_code |
226 |
251 |
context['conflicts'] = conflicts |
227 |
252 |
print(context['time_blocks']) |
228 |
253 |
return render(request, template, context) |
229 |
254 |
|
230 |
255 |
def login(request): |
231 |
256 |
context = dict() |
232 |
257 |
#context = {'money' : update_balance(None)} |
233 |
258 |
if request.method == "POST": |
234 |
259 |
name = request.POST['name'] |
235 |
260 |
passphrase = request.POST['pass'] |
236 |
261 |
user = authenticate(username=name, password=passphrase) |
237 |
262 |
if user is not None: # The user was successfully authenticated |
238 |
263 |
print("YA") |
239 |
264 |
return HttpResponseRedirect(request.POST['next']) |
240 |
265 |
else: # User credentials were wrong |
241 |
266 |
context['next'] = request.POST['next'] |
242 |
267 |
context['message'] = _("The given credentials were not correct.") |
243 |
268 |
else: |
244 |
269 |
context['next'] = request.GET.get('next', None) |
245 |
270 |
if context['next'] is None: |
246 |
271 |
context['next'] = reverse('administration-index') |
247 |
272 |
|
248 |
273 |
template = 'administration/login.djhtml' |
249 |
274 |
|
250 |
275 |
return render(request, template, context) |
251 |
276 |
courses/templates/courses/index.djhtml ¶
1 addition and 1 deletion.
View changes Hide changes
1 |
1 |
{% load i18n %} |
2 |
2 |
|
3 |
3 |
{% block title %} |
4 |
4 |
{#{% trans "◀ Joeni /▶ | Courses" %}#} |
5 |
5 |
{% trans "Courses" %} | {{ block.super }} |
6 |
6 |
{% endblock %} |
7 |
7 |
|
8 |
8 |
{% block main %} |
9 |
9 |
<h1>{% trans "Your courses" %}</h1> |
10 |
10 |
<div class="flex-container"> |
11 |
11 |
{% for course in courses %} |
12 |
12 |
<a class="flex-items" style="background-color: #{{ course.color }};" flex-wrapper" href="{% url 'courses-course-index' course_slug=course.slug_name %}"> |
13 |
- | {{ course }}<br /> |
+ |
13 |
{{ course }}<br /> |
14 |
14 |
</a> |
15 |
15 |
{% endfor %} |
16 |
16 |
</div> |
17 |
17 |
{% endblock main %} |
18 |
18 |
static/css/header.scss ¶
1 addition and 1 deletion.
View changes Hide changes
1 |
1 |
float: left; |
2 |
2 |
margin-right: 50px; |
3 |
3 |
position: fixed; |
4 |
4 |
//display: flow; |
5 |
5 |
//height: 100%; |
6 |
6 |
padding: $header-padding; |
7 |
7 |
top: 0; |
8 |
8 |
width: $header-width; |
9 |
9 |
height: 100%; |
10 |
10 |
//background-color: $uhasselt-color; |
11 |
11 |
color: white; |
12 |
12 |
img { |
13 |
13 |
height: 5em; |
14 |
- | } |
+ |
14 |
} |
15 |
15 |
nav ul { |
16 |
16 |
//list-style: none; |
17 |
17 |
list-style: none; |
18 |
18 |
} |
19 |
19 |
a { |
20 |
20 |
text-decoration: none; |
21 |
21 |
color: white; |
22 |
22 |
&:hover { |
23 |
23 |
text-decoration: underline solid white; |
24 |
24 |
text-transform: uppercase; |
25 |
25 |
font-weight: bold; |
26 |
26 |
} |
27 |
27 |
} |
28 |
28 |
} |
29 |
29 |
/*header ul { |
30 |
30 |
display: inline; |
31 |
31 |
float: right; |
32 |
32 |
}*/ |
33 |
33 |