diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py
index 5afeb2c..225ace3 100644
--- a/apiserver/apiserver/api/views.py
+++ b/apiserver/apiserver/api/views.py
@@ -230,7 +230,7 @@ class CardViewSet(Base, Create, Retrieve, Update, Destroy):
class CourseViewSet(Base, List, Retrieve, Create, Update):
- permission_classes = [AllowMetadata | IsAuthenticated, IsAdminOrReadOnly | IsInstructorOrReadOnly]
+ permission_classes = [AllowMetadata | IsAuthenticatedOrReadOnly, IsAdminOrReadOnly | IsInstructorOrReadOnly]
queryset = models.Course.objects.annotate(date=Max('sessions__datetime')).order_by('-date')
def get_serializer_class(self):
@@ -241,7 +241,7 @@ class CourseViewSet(Base, List, Retrieve, Create, Update):
class SessionViewSet(Base, List, Retrieve, Create, Update):
- permission_classes = [AllowMetadata | IsAuthenticated, IsAdminOrReadOnly | IsInstructorOrReadOnly]
+ permission_classes = [AllowMetadata | IsAuthenticatedOrReadOnly, IsAdminOrReadOnly | IsInstructorOrReadOnly]
def get_queryset(self):
if self.action == 'list':
diff --git a/webclient/src/App.js b/webclient/src/App.js
index 8daf355..afaa378 100644
--- a/webclient/src/App.js
+++ b/webclient/src/App.js
@@ -18,7 +18,7 @@ import { Admin } from './Admin.js';
import { Paste } from './Paste.js';
import { Sign } from './Sign.js';
import { Courses, CourseDetail } from './Courses.js';
-import { Classes, ClassDetail } from './Classes.js';
+import { ClassFeed, Classes, ClassDetail } from './Classes.js';
import { Members, MemberDetail } from './Members.js';
import { Charts } from './Charts.js';
import { Auth } from './Auth.js';
@@ -112,206 +112,216 @@ function App() {
-
-
-
-
-
-
+
+
+
+
- {window.location.hostname !== 'my.protospace.ca' &&
- ~~~~~ Development site ~~~~~
- }
-
+
+
+
+
+
+
+
-
-
+ {user && isAdmin(user) && }
-
-
-
+ {user && isAdmin(user) && }
+
+
-
-
-
-
-
-
-
+ {user &&
+
+
+ }
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {user && user.member.set_details ?
+
-
-
+
+
+
+
+
-
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
+ {user && user.member.set_details ?
+
+
+
+
- {user && isAdmin(user) &&
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {user && isAdmin(user) &&
+
+
+
+ }
+
+ {user && isAdmin(user) &&
+
+
+
+ }
+
+
+
+
+
+ :
+
+
}
-
- {user && isAdmin(user) &&
-
-
-
- }
-
-
-
-
- :
-
-
-
- }
-
-
+
+
+
diff --git a/webclient/src/Classes.js b/webclient/src/Classes.js
index c961986..dd9d105 100644
--- a/webclient/src/Classes.js
+++ b/webclient/src/Classes.js
@@ -50,6 +50,43 @@ function ClassTable(props) {
let classesCache = false;
+export function ClassFeed(props) {
+ const [classes, setClasses] = useState(classesCache);
+
+ useEffect(() => {
+ const get = async() => {
+ requester('/sessions/', 'GET', '')
+ .then(res => {
+ setClasses(res.results);
+ classesCache = res.results;
+ })
+ .catch(err => {
+ console.log(err);
+ });
+ };
+
+ get();
+ const interval = setInterval(get, 60000);
+ return () => clearInterval(interval);
+ }, []);
+
+ const now = new Date().toISOString();
+
+ return (
+
+
+
+ Upcoming Protospace Classes
+
+ {classes ?
+ x.datetime > now).sort((a, b) => a.datetime > b.datetime ? 1 : -1)} />
+ :
+ Loading...
+ }
+
+ );
+};
+
export function Classes(props) {
const [classes, setClasses] = useState(classesCache);
const { token } = props;