diff --git a/src/project/templates/base.html b/src/project/templates/base.html
index 6aaa0b3..59e285f 100644
--- a/src/project/templates/base.html
+++ b/src/project/templates/base.html
@@ -51,7 +51,7 @@
-
+
Services
diff --git a/src/project/views.py b/src/project/views.py
index a8e8dae..42008c2 100644
--- a/src/project/views.py
+++ b/src/project/views.py
@@ -1,7 +1,5 @@
from django_view_decorator import view
-from membership.models import ServiceAccess
-from services.registry import ServiceRegistry
from utils.view_utils import render
@@ -12,36 +10,3 @@ from utils.view_utils import render
)
def index(request):
return render(request, "index.html")
-
-
-@view(
- paths="services/",
- name="services",
- login_required=True,
-)
-def services_overview(request):
- active_services = [
- access.service_implementation
- for access in ServiceAccess.objects.filter(
- user=request.user,
- )
- ]
-
- active_service_classes = [service.__class__ for service in active_services]
-
- services = [
- service
- for _, service in ServiceRegistry.get_items()
- if service not in active_service_classes
- ]
-
- context = {
- "non_active_services": services,
- "active_services": active_services,
- }
-
- return render(
- request=request,
- template_name="services_overview.html",
- context=context,
- )
diff --git a/src/services/registry.py b/src/services/registry.py
index f80926d..70b5044 100644
--- a/src/services/registry.py
+++ b/src/services/registry.py
@@ -1,3 +1,4 @@
+from django import forms
from django_registries.registry import Interface
from django_registries.registry import Registry
@@ -23,3 +24,17 @@ class ServiceInterface(Interface):
# - maybe a list of tuples with the field name and the type of the field
# this could be used to generate a form for the service, and also to validate
# the data saved in a JSONField on the ServiceAccess model
+
+ subscribe_fields: list[tuple[str, forms.Field]] = []
+
+ def get_form(self) -> type:
+ """Get the form for the service"""
+ print(self.subscribe_fields)
+ return type(
+ "ServiceForm",
+ (forms.Form,),
+ {
+ field_name: field_type
+ for field_name, field_type in self.subscribe_fields
+ },
+ )()
diff --git a/src/services/services.py b/src/services/services.py
index f5e4998..9d5135d 100644
--- a/src/services/services.py
+++ b/src/services/services.py
@@ -1,3 +1,5 @@
+from django import forms
+
from .registry import ServiceInterface
@@ -14,6 +16,10 @@ class MatrixService(ServiceInterface):
url = "https://matrix.data.coop"
description = "Matrix service for data.coop"
+ subscribe_fields = [
+ ("username", forms.CharField()),
+ ]
+
class MastodonService(ServiceInterface):
slug = "mastodon"
diff --git a/src/services/templates/services/service_detail.html b/src/services/templates/services/service_detail.html
new file mode 100644
index 0000000..3f67084
--- /dev/null
+++ b/src/services/templates/services/service_detail.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
+
{{ service.name }}
+
+
+{% endblock %}
diff --git a/src/services/templates/services/service_subscribe.html b/src/services/templates/services/service_subscribe.html
new file mode 100644
index 0000000..8df66cb
--- /dev/null
+++ b/src/services/templates/services/service_subscribe.html
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
+
Subscribe to {{ service.name }}
+
+
+
+
+
+{% endblock %}
diff --git a/src/project/templates/services_overview.html b/src/services/templates/services/services_overview.html
similarity index 81%
rename from src/project/templates/services_overview.html
rename to src/services/templates/services/services_overview.html
index 4678c4c..ba13a55 100644
--- a/src/project/templates/services_overview.html
+++ b/src/services/templates/services/services_overview.html
@@ -28,11 +28,16 @@
- Subscribe
+ Subscribe
{% endfor %}
diff --git a/src/services/views.py b/src/services/views.py
index 60f00ef..2eddf92 100644
--- a/src/services/views.py
+++ b/src/services/views.py
@@ -1 +1,86 @@
# Create your views here.
+from django_view_decorator import namespaced_decorator_factory
+
+from membership.models import ServiceAccess
+from services.registry import ServiceRegistry
+from utils.view_utils import render
+
+
+services_view = namespaced_decorator_factory(
+ namespace="services",
+ base_path="services",
+)
+
+
+@services_view(
+ paths="",
+ name="list",
+ login_required=True,
+)
+def services_overview(request):
+ active_services = [
+ access.service_implementation
+ for access in ServiceAccess.objects.filter(
+ user=request.user,
+ )
+ ]
+
+ active_service_classes = [service.__class__ for service in active_services]
+
+ services = [
+ service
+ for _, service in ServiceRegistry.get_items()
+ if service not in active_service_classes
+ ]
+
+ context = {
+ "non_active_services": services,
+ "active_services": active_services,
+ }
+
+ return render(
+ request=request,
+ template_name="services/services_overview.html",
+ context=context,
+ )
+
+
+@services_view(
+ paths="/",
+ name="detail",
+ login_required=True,
+)
+def service_detail(request, service_slug):
+ service = ServiceRegistry.get(slug=service_slug)
+
+ context = {
+ "service": service,
+ }
+
+ return render(
+ request=request,
+ template_name="services/service_detail.html",
+ context=context,
+ )
+
+
+@services_view(
+ paths="/subscribe/",
+ name="subscribe",
+ login_required=True,
+)
+def service_subscribe(request, service_slug):
+ service = ServiceRegistry.get(slug=service_slug)
+
+ # TODO: add a form to subscribe to the service
+ context = {
+ "service": service,
+ "base_path": "services:list",
+ "form": service.get_form(),
+ }
+
+ return render(
+ request=request,
+ template_name="services/service_subscribe.html",
+ context=context,
+ )