Skip to content
Snippets Groups Projects
Commit 1294a2a4 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Show events | Get information about user

parent 6f37d9b5
No related branches found
No related tags found
1 merge request!86Merge school-apps
......@@ -11,7 +11,8 @@ class Dashboard extends React.Component {
constructor() {
super();
this.state = {
refreshIn: REFRESH_TIME
refreshIn: REFRESH_TIME,
isLoading: true
};
}
......@@ -33,7 +34,7 @@ class Dashboard extends React.Component {
$.getJSON(API_URL, (data) => {
console.log(data);
if (data) {
that.setState({...data, refreshIn: REFRESH_TIME + 1});
that.setState({...data, refreshIn: REFRESH_TIME + 1, isLoading: false});
that.updateRefreshTime();
}
})
......@@ -56,7 +57,29 @@ class Dashboard extends React.Component {
}
render() {
if (this.state.isLoading) {
return <div className={"row center-via-flex container"} style={{"height": "10em"}}>
<div className={"center2-via-flex"}>
<div className="preloader-wrapper big active">
<div className="spinner-layer spinner-primary">
<div className="circle-clipper left">
<div className="circle"/>
</div>
<div className="gap-patch">
<div className="circle"/>
</div>
<div className="circle-clipper right">
<div className="circle"/>
</div>
</div>
</div>
<p className={"text-center"}>Wird geladen </p>
</div>
</div>;
}
const that = this;
console.log(MY_PLAN_URL);
return <div>
<button className={"btn-flat right grey-text"} onClick={this.updateData}>
<i className={"material-icons left"}>refresh</i>
......@@ -85,33 +108,30 @@ class Dashboard extends React.Component {
<div className={"col s12 m6 l6 xl8 no-padding"}>
<div className="col s12 m12 l12 xl6">
<div className="card">
<div className="card-content">
<span className="card-title">Vertretungen der <em>Eb</em> für heute</span>
<p>I am a very simple card. I am good at containing small bits of information.
I am convenient because I require little markup to use effectively.</p>
</div>
<div className="card-action">
<a href="#">
{this.state.has_plan ? <div className="card-content">
<span className="card-title">Vertretungen {this.state.plan.type == 2 ? "der" : "für"}
<em>{this.state.plan.name}</em> für {this.state.date_formatted}</span>
<p>Keine Vertretungen für morgen vorhanden.</p>
</div> : <p className={"flow-text"}>Keine Vertretungen vorhanden.</p>}
{this.state.has_plan ? <div className="card-action">
<a href={MY_PLAN_URL}>
<span className="badge new primary-color card-action-badge">SMART PLAN</span>
anzeigen
</a>
</div>
</div> : ""}
</div>
</div>
<div className="col s12 m12 l12 xl6">
<div className="card">
<div className="card-content">
<span className="card-title">Aktuelle Termine</span>
<div className="card-panel event-card">
<span className={"title"}>Sextanereinschulung</span>
<br/>
28.Aug. 2019 18:30 - 22:00
</div>
<div className="card-panel event-card">
<span className={"title"}>Sextanereinschulung</span>
<br/>
28.Aug. 2019 18:30 - 22:00
</div>
{this.state.current_events && this.state.current_events.length > 0 ? this.state.current_events.map(function (event) {
return <div className="card-panel event-card">
<span className={"title"}>{event.name}</span>
<br/>
{event.formatted}
</div>;
}) : "Keine aktuellen Termine"}
</div>
<div className="card-action">
<a href="https://katharineum-zu-luebeck.de/aktuelles/termine/">Weitere Termine</a>
......
......@@ -9,4 +9,5 @@ django_react_templatetags
kanboard
PyPDF2
martor
django_widget_tweaks
\ No newline at end of file
django_widget_tweaks
ics
\ No newline at end of file
# Generated by Django 2.2.1 on 2019-09-01 08:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dashboard', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='notification',
name='read',
field=models.BooleanField(default=False),
),
]
......@@ -4,6 +4,7 @@
<main>
<script>
var API_URL = "{% url "api_information" %}";
var MY_PLAN_URL = "{% url "timetable_my_plan" %}";
</script>
<script src="{% static "js/react/react.development.js" %}"></script>
<script src="{% static "js/react/react-dom.development.js" %}"></script>
......
......@@ -2,8 +2,13 @@ from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.utils import timezone
from helper import get_newest_articles
from helper import get_newest_articles, get_current_events
from schoolapps.settings import SHORT_WEEK_DAYS, LONG_WEEK_DAYS
from timetable.hints import get_all_hints_by_class_and_time_period, get_all_hints_for_teachers_by_time_period
from timetable.views import get_next_weekday_with_time, get_type_and_object_of_user
from untisconnect.api import TYPE_TEACHER, TYPE_CLASS
from .models import Activity, register_notification, Notification
# from .apps import DashboardConfig
from mailer import send_mail_with_template
......@@ -38,6 +43,38 @@ def api_information(request):
else:
newest_article = None
print(newest_articles)
next_weekday = get_next_weekday_with_time(timezone.now(), timezone.now().time())
if next_weekday.date() == timezone.now().date():
date_formatted = "heute"
print("Gleicher Tag")
elif next_weekday.date() == timezone.now().date() + timezone.timedelta(days=1):
print("Nächster Tag")
date_formatted = "morgen"
else:
print("Ganz anderer Tag")
date_formatted = LONG_WEEK_DAYS[next_weekday.isoweekday() - 2]
# Get user type (student, teacher, etc.)
_type, el = get_type_and_object_of_user(request.user)
hints = None
if _type == TYPE_TEACHER:
# Teacher
plan_id = el.id
raw_type = "teacher"
# Get hints
# hints = list(get_all_hints_for_teachers_by_time_period(next_weekday, next_weekday))
elif _type == TYPE_CLASS:
# Student
plan_id = el.id
raw_type = "class"
# Get hints
# hints = list(get_all_hints_by_class_and_time_period(el, next_weekday, next_weekday))
context = {
'activities': list(activities.values()),
'notifications': list(notifications.values()),
......@@ -49,7 +86,20 @@ def api_information(request):
'subjects': UserInformation.user_subjects(request.user),
'has_wifi': UserInformation.user_has_wifi(request.user),
"newest_article": newest_article,
"current_events": get_current_events()[:3],
"date_formatted": date_formatted,
}
if _type is not None:
context["plan"] = {
"type": _type,
"name": el.shortcode if _type == TYPE_TEACHER else el.name,
"hints": hints
}
context["has_plan"] = True
else:
context["has_plan"] = False
print(context)
return JsonResponse(context)
......
......@@ -2,6 +2,10 @@ import os
from uuid import uuid4
from django.template.loader_tags import register
from datetime import datetime
from django.utils import timezone, formats
from ics import Calendar
def path_and_rename(instance, filename):
......@@ -65,3 +69,48 @@ def get_newest_articles(domain, limit=0, author_blacklist=None):
break
return posts
CALENDAR_URL = "https://nimbus.katharineum.de/remote.php/dav/public-calendars/owit7yysLB2CYNTq?export"
def get_current_events():
c = Calendar(requests.get(CALENDAR_URL).text)
print(c.events)
e = list(c.timeline)[0]
print(c.timeline.today())
i = 0
events = []
for event in c.timeline.start_after(timezone.now()):
if i >= 5:
break
i += 1
begin_date_formatted = formats.date_format(event.begin)
end_date_formatted = formats.date_format(event.end)
begin_time_formatted = formats.time_format(event.begin.time())
end_time_formatted = formats.time_format(event.end.time())
if event.begin.date() == event.end.date():
formatted = begin_date_formatted
if not event.all_day:
formatted += " " + begin_time_formatted
if event.begin.time != event.end.time():
formatted += "" + end_time_formatted
else:
if event.all_day:
formatted = "{} – {}".format(begin_date_formatted, end_date_formatted)
else:
formatted = "{} {} – {} {}".format(begin_date_formatted, begin_time_formatted, end_date_formatted,
end_time_formatted)
print(formatted)
print(formats.date_format(event.begin))
events.append({
"name": event.name,
# "begin": event.begin,
# "end": event.end,
"formatted": formatted
})
# print(event)
print(events)
print("Event '{}' started {}".format(e.name, e.begin.humanize()))
return events
......@@ -598,4 +598,20 @@ i.collapsible-trigger {
border-radius: 0 3px 3px 0;
text-transform: uppercase;
font-weight: 300;
}
.center-via-flex {
display: flex;
align-items: center;
justify-content: center;
}
.center2-via-flex {
display: flex;
flex-direction: column;
align-items: center;
}
.spinner-primary {
border-color: #da1f3d;
}
\ No newline at end of file
......@@ -85,14 +85,15 @@ var Dashboard = function (_React$Component) {
$.getJSON(API_URL, function (data) {
console.log(data);
if (data) {
that.setState(Object.assign({}, data, {refreshIn: REFRESH_TIME + 1}));
that.setState(Object.assign({}, data, {refreshIn: REFRESH_TIME + 1, isLoading: false}));
that.updateRefreshTime();
}
});
};
_this.state = {
refreshIn: REFRESH_TIME
refreshIn: REFRESH_TIME,
isLoading: true
};
return _this;
}
......@@ -118,7 +119,47 @@ var Dashboard = function (_React$Component) {
}, {
key: "render",
value: function render() {
if (this.state.isLoading) {
return React.createElement(
"div",
{className: "row center-via-flex container", style: {"height": "10em"}},
React.createElement(
"div",
{className: "center2-via-flex"},
React.createElement(
"div",
{className: "preloader-wrapper big active"},
React.createElement(
"div",
{className: "spinner-layer spinner-primary"},
React.createElement(
"div",
{className: "circle-clipper left"},
React.createElement("div", {className: "circle"})
),
React.createElement(
"div",
{className: "gap-patch"},
React.createElement("div", {className: "circle"})
),
React.createElement(
"div",
{className: "circle-clipper right"},
React.createElement("div", {className: "circle"})
)
)
),
React.createElement(
"p",
{className: "text-center"},
"Wird geladen \u2026"
)
)
);
}
var that = this;
console.log(MY_PLAN_URL);
return React.createElement(
"div",
null,
......@@ -196,32 +237,39 @@ var Dashboard = function (_React$Component) {
React.createElement(
"div",
{className: "card"},
React.createElement(
this.state.has_plan ? React.createElement(
"div",
{className: "card-content"},
React.createElement(
"span",
{className: "card-title"},
"Vertretungen der ",
"Vertretungen ",
this.state.plan.type == 2 ? "der" : "für",
" ",
React.createElement(
"em",
null,
"Eb"
this.state.plan.name
),
" f\xFCr heute"
" f\xFCr ",
this.state.date_formatted
),
React.createElement(
"p",
null,
"I am a very simple card. I am good at containing small bits of information. I am convenient because I require little markup to use effectively."
"Keine Vertretungen f\xFCr morgen vorhanden."
)
) : React.createElement(
"p",
{className: "flow-text"},
"Keine Vertretungen vorhanden."
),
React.createElement(
this.state.has_plan ? React.createElement(
"div",
{className: "card-action"},
React.createElement(
"a",
{href: "#"},
{href: MY_PLAN_URL},
React.createElement(
"span",
{className: "badge new primary-color card-action-badge"},
......@@ -229,7 +277,7 @@ var Dashboard = function (_React$Component) {
),
"anzeigen"
)
)
) : ""
)
),
React.createElement(
......@@ -246,28 +294,19 @@ var Dashboard = function (_React$Component) {
{className: "card-title"},
"Aktuelle Termine"
),
React.createElement(
"div",
{className: "card-panel event-card"},
React.createElement(
"span",
{className: "title"},
"Sextanereinschulung"
),
React.createElement("br", null),
"28.Aug. 2019 18:30 - 22:00"
),
React.createElement(
"div",
{className: "card-panel event-card"},
React.createElement(
"span",
{className: "title"},
"Sextanereinschulung"
),
React.createElement("br", null),
"28.Aug. 2019 18:30 - 22:00"
)
this.state.current_events && this.state.current_events.length > 0 ? this.state.current_events.map(function (event) {
return React.createElement(
"div",
{className: "card-panel event-card"},
React.createElement(
"span",
{className: "title"},
event.name
),
React.createElement("br", null),
event.formatted
);
}) : "Keine aktuellen Termine"
),
React.createElement(
"div",
......
# Generated by Django 2.2.1 on 2019-09-01 08:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timetable', '0009_hint_classes_formatted'),
]
operations = [
migrations.AlterField(
model_name='hintclass',
name='class_id',
field=models.IntegerField(),
),
]
......@@ -203,6 +203,28 @@ def plan(request, plan_type, plan_id, regular="", year=timezone.datetime.now().y
return render(request, 'timetable/plan.html', context)
def get_type_and_object_of_user(user):
_type = UserInformation.user_type(user)
if _type == UserInformation.TEACHER:
# Teacher
_type = TYPE_TEACHER
shortcode = user.username
el = get_teacher_by_shortcode(shortcode)
plan_id = el.id
raw_type = "teacher"
elif _type == UserInformation.STUDENT:
# Student
_type = TYPE_CLASS
_name = UserInformation.user_classes(user)[0]
el = get_class_by_name(_name)
plan_id = el.id
raw_type = "class"
else:
return None, None
return _type, el
@login_required
@permission_required("timetable.show_plan")
def my_plan(request, year=None, month=None, day=None):
......@@ -223,13 +245,9 @@ def my_plan(request, year=None, month=None, day=None):
monday_of_week = get_calendar_week(calendar_week, date.year)["first_day"]
# Get user type (student, teacher, etc.)
_type = UserInformation.user_type(request.user)
if _type == UserInformation.TEACHER:
_type, el = get_type_and_object_of_user(request.user)
if _type == TYPE_TEACHER:
# Teacher
_type = TYPE_TEACHER
shortcode = request.user.username
el = get_teacher_by_shortcode(shortcode)
plan_id = el.id
raw_type = "teacher"
......@@ -237,11 +255,9 @@ def my_plan(request, year=None, month=None, day=None):
hints = list(get_all_hints_for_teachers_by_time_period(date, date))
hints_b = list(get_all_hints_not_for_teachers_by_time_period(date, date))
elif _type == UserInformation.STUDENT:
elif _type == TYPE_CLASS:
# Student
_type = TYPE_CLASS
_name = UserInformation.user_classes(request.user)[0]
el = get_class_by_name(_name)
plan_id = el.id
raw_type = "class"
......@@ -275,7 +291,7 @@ def my_plan(request, year=None, month=None, day=None):
return render(request, 'timetable/myplan.html', context)
def get_next_weekday_with_time(date, time):
def get_next_weekday_with_time(date, time) -> datetime.datetime:
"""Get the next weekday by a datetime object"""
if time > datetime.time(15, 35):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment