diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py
index ea42a46..7b3dda6 100644
--- a/apiserver/apiserver/api/models.py
+++ b/apiserver/apiserver/api/models.py
@@ -142,6 +142,13 @@ class Training(models.Model):
history = HistoricalRecords()
+class Interest(models.Model):
+ user = models.ForeignKey(User, related_name='interests', null=True, on_delete=models.SET_NULL)
+ course = models.ForeignKey(Course, related_name='courses', null=True, on_delete=models.SET_NULL)
+
+ satisfied_by = models.ForeignKey(Session, related_name='satisfies', null=True, on_delete=models.SET_NULL)
+
+
class MetaInfo(models.Model):
backup_id = models.TextField()
diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py
index 861f95f..ec3efa0 100644
--- a/apiserver/apiserver/api/serializers.py
+++ b/apiserver/apiserver/api/serializers.py
@@ -521,10 +521,18 @@ class UserTrainingSerializer(serializers.ModelSerializer):
exclude = ['user']
depth = 2
+class InterestSerializer(serializers.ModelSerializer):
+ course = serializers.PrimaryKeyRelatedField(queryset=models.Course.objects.all())
+ class Meta:
+ model = models.Interest
+ fields = '__all__'
+ read_only_fields = ['user', 'satisfied_by']
+
class UserSerializer(serializers.ModelSerializer):
training = UserTrainingSerializer(many=True)
member = MemberSerializer()
transactions = serializers.SerializerMethodField()
+ interests = serializers.SerializerMethodField()
door_code = serializers.SerializerMethodField()
wifi_pass = serializers.SerializerMethodField()
app_version = serializers.SerializerMethodField()
@@ -543,6 +551,7 @@ class UserSerializer(serializers.ModelSerializer):
'wifi_pass',
'app_version',
#'usages',
+ 'interests',
]
depth = 1
@@ -554,6 +563,13 @@ class UserSerializer(serializers.ModelSerializer):
serializer.is_valid()
return serializer.data
+ def get_interests(self, obj):
+ interests = models.Interest.objects.filter(
+ user=obj,
+ satisfied_by__isnull=True
+ )
+ return [x.course.id for x in interests]
+
def get_door_code(self, obj):
if not obj.member.paused_date and obj.cards.count():
return secrets.DOOR_CODE
diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py
index 6d0abf8..a0dcada 100644
--- a/apiserver/apiserver/api/views.py
+++ b/apiserver/apiserver/api/views.py
@@ -992,6 +992,24 @@ class UsageViewSet(Base):
return response
+class InterestViewSet(Base, Retrieve, Create):
+ permission_classes = [AllowMetadata | IsAuthenticated]
+ queryset = models.Interest.objects.all()
+ serializer_class = serializers.InterestSerializer
+
+ def perform_create(self, serializer):
+ user = self.request.user
+ course = self.request.data['course']
+
+ interest = models.Interest.objects.filter(user=user, course=course, satisfied_by__isnull=True)
+ if interest.exists():
+ raise exceptions.ValidationError(dict(non_field_errors='Already interested'))
+
+ serializer.save(
+ user=user,
+ satisfied_by=None
+ )
+
class RegistrationView(RegisterView):
serializer_class = serializers.MyRegisterSerializer
diff --git a/apiserver/apiserver/urls.py b/apiserver/apiserver/urls.py
index 65c98b7..16119b8 100644
--- a/apiserver/apiserver/urls.py
+++ b/apiserver/apiserver/urls.py
@@ -21,6 +21,7 @@ router.register(r'history', views.HistoryViewSet, basename='history')
router.register(r'vetting', views.VettingViewSet, basename='vetting')
router.register(r'sessions', views.SessionViewSet, basename='session')
router.register(r'training', views.TrainingViewSet, basename='training')
+router.register(r'interest', views.InterestViewSet, basename='interest')
router.register(r'transactions', views.TransactionViewSet, basename='transaction')
router.register(r'charts/membercount', views.MemberCountViewSet, basename='membercount')
router.register(r'charts/signupcount', views.SignupCountViewSet, basename='signupcount')
diff --git a/webclient/src/App.js b/webclient/src/App.js
index f972f2f..7a15ad5 100644
--- a/webclient/src/App.js
+++ b/webclient/src/App.js
@@ -260,7 +260,7 @@ function App() {
Error. No upcoming classes.
+
+ :
+ <>
+
+
No upcoming classes.
-