diff --git a/aleksis/apps/paweljong/filters.py b/aleksis/apps/paweljong/filters.py
index 430b07b5d05a626d0d53254c0bf4517cf679e392..7ae7dc2ae39c7bc2ca965b8befd7b864d08a63e3 100644
--- a/aleksis/apps/paweljong/filters.py
+++ b/aleksis/apps/paweljong/filters.py
@@ -11,13 +11,13 @@ from .models import Event, EventRegistration, Terms, Voucher
 class EventRegistrationFilter(FilterSet):
     class Meta:
         model = EventRegistration
-        fields = ["person", "event", "accept_sepa", "date_registered"]
+        fields = ["person", "event", "accept_sepa", "date_registered", "states"]
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
         self.form.layout = Layout(
-            Row("person", "event"),
+            Row("person", "event", "states"),
             Row("accept_sepa", "date_registered"),
         )
 
diff --git a/aleksis/apps/paweljong/forms.py b/aleksis/apps/paweljong/forms.py
index 8a51d714bb6b574bc8412ed83d535800d6f16fb3..d710f90b299d7a74250df8b2967223f1d453bc6a 100644
--- a/aleksis/apps/paweljong/forms.py
+++ b/aleksis/apps/paweljong/forms.py
@@ -11,7 +11,7 @@ from phonenumber_field.formfields import PhoneNumberField
 from aleksis.core.mixins import ExtensibleForm
 from aleksis.core.models import Group, Person
 
-from .models import Event, EventRegistration, InfoMailing, Terms, Voucher
+from .models import Event, EventRegistration, InfoMailing, Terms, Voucher, RegistrationState
 
 COMMENT_CHOICES = [
     ("first", _("Only first name")),
@@ -404,20 +404,13 @@ class RegisterEventConsent(ExtensibleForm):
 class EditEventRegistrationForm(forms.ModelForm):
 
     layout = Layout(
-        Fieldset(
-            _("General event information"),
-            Row("event", "person"),
-            Row("comment"),
-        ),
-        Fieldset(
-            _("Financial data"),
-            "voucher_code",
-            Row("iban", "donation", "accept_sepa"),
-        ),
-        Fieldset(
-            _("Declaration of consent"),
-            Row("accept_terms", "accept_data", "accept_general_terms"),
-        ),
+        Row("event", "person"),
+        Row("comment", "medical_information"),
+        "voucher",
+        Row("iban", "donation", "accept_sepa"),
+        "accepted_terms",
+        Row("school", "school_class", "school_place"),
+        "states",
     )
 
     class Meta:
@@ -490,3 +483,9 @@ class RegistrationNotificationForm(forms.ModelForm):
     class Meta:
         model = InfoMailing
         exclude = ["sent_to", "active"]
+
+
+class RegistrationStatesForm(forms.ModelForm):
+    class Meta:
+        model = RegistrationState
+        exclude = []
diff --git a/aleksis/apps/paweljong/menus.py b/aleksis/apps/paweljong/menus.py
index afe3056df07a741f0bd94d2bb1db4a015c532907..149cd54a637869ca14489f308f5caaf87ec7c370 100644
--- a/aleksis/apps/paweljong/menus.py
+++ b/aleksis/apps/paweljong/menus.py
@@ -44,6 +44,17 @@ MENUS = {
                         )
                     ],
                 },
+                {
+                    "name": _("Registration states"),
+                    "url": "registration_states",
+                    "icon": "list",
+                    "validators": [
+                        (
+                            "aleksis.core.util.predicates.permission_validator",
+                            "paweljong.view_registration_states_rule",
+                        )
+                    ],
+                },
                 {
                     "name": _("Info mailings"),
                     "url": "info_mailings",
diff --git a/aleksis/apps/paweljong/migrations/0015_registrationstate.py b/aleksis/apps/paweljong/migrations/0015_registrationstate.py
new file mode 100644
index 0000000000000000000000000000000000000000..6375c85243be833a5959998dcaac47c7a8e08197
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0015_registrationstate.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.2.12 on 2022-03-06 20:09
+
+import colorfield.fields
+import django.contrib.sites.managers
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('sites', '0002_alter_domain_unique'),
+        ('paweljong', '0014_move_sent_to_to_through'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='RegistrationState',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('extended_data', models.JSONField(default=dict, editable=False)),
+                ('name', models.CharField(max_length=255, verbose_name='Name of State')),
+                ('colour', colorfield.fields.ColorField(blank=True, default='', image_field=None, max_length=18, samples=None, verbose_name='Colour')),
+                ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
+            ],
+            options={
+                'abstract': False,
+            },
+            managers=[
+                ('objects', django.contrib.sites.managers.CurrentSiteManager()),
+            ],
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py b/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py
new file mode 100644
index 0000000000000000000000000000000000000000..28e9964684d80e108fcff1e8a89ef18f34268ecf
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0016_eventregistration_states.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.12 on 2022-03-06 20:30
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('paweljong', '0015_registrationstate'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='eventregistration',
+            name='states',
+            field=models.ManyToManyField(related_name='registrations', to='paweljong.RegistrationState', verbose_name='States'),
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/models.py b/aleksis/apps/paweljong/models.py
index 976b74470226a61ccf67a24835c5833388e64230..0fb4b3c407f2336dfe0b39bf72dd166fc4b5a642 100644
--- a/aleksis/apps/paweljong/models.py
+++ b/aleksis/apps/paweljong/models.py
@@ -8,6 +8,7 @@ from django.utils.translation import gettext_lazy as _
 
 from ckeditor.fields import RichTextField
 from django_iban.fields import IBANField
+from colorfield.fields import ColorField
 
 from aleksis.core.mixins import ExtensibleModel
 from aleksis.core.models import Group, Person
@@ -15,6 +16,15 @@ from aleksis.core.util.core_helpers import generate_random_code, get_site_prefer
 from aleksis.core.util.email import send_email
 
 
+class RegistrationState(ExtensibleModel):
+
+    name = models.CharField(verbose_name=_("Name"), max_length=255)
+    colour = ColorField(blank=True, verbose_name=_("Colour"))
+
+    def __str__(self) -> str:
+        return self.name
+
+
 class Terms(ExtensibleModel):
     title = models.CharField(max_length=255, verbose_name=_("Title"))
     term = RichTextField(verbose_name=_("Term"))
@@ -261,6 +271,8 @@ class EventRegistration(ExtensibleModel):
         blank=True,
     )
 
+    states = models.ManyToManyField(RegistrationState, verbose_name=_("States"), related_name="registrations")
+
     def __str__(self) -> str:
         return f"{self.event}, {self.person.first_name} {self.person.last_name}"
 
diff --git a/aleksis/apps/paweljong/tables.py b/aleksis/apps/paweljong/tables.py
index 2e7ac691d402d6c72ac1437eb5a7666146fe1e20..8795e17ab9a60770558f6013a682db13ecfba49a 100644
--- a/aleksis/apps/paweljong/tables.py
+++ b/aleksis/apps/paweljong/tables.py
@@ -1,3 +1,4 @@
+from django.template.loader import render_to_string
 from django.utils.translation import ugettext_lazy as _
 
 import django_tables2 as tables
@@ -56,13 +57,23 @@ class EventRegistrationsTable(tables.Table):
     person = tables.Column()
     event = tables.Column()
     date_registered = tables.Column()
+    states = tables.Column()
     view = tables.LinkColumn(
         "registration_by_pk",
         args=[A("id")],
         verbose_name=_("View registration"),
         text=_("View"),
     )
+    edit = tables.LinkColumn(
+        "edit_registration_by_pk",
+        args=[A("pk")],
+        verbose_name=_("Edit"),
+        text=_("Edit"),
+    )
 
+    def render_states(self, value, record):
+        context = dict(states=value.all())
+        return render_to_string("paweljong/registration_state/chip.html", context)
 
 class TermsTable(tables.Table):
     class Meta:
@@ -96,3 +107,21 @@ class InfoMailingsTable(tables.Table):
         verbose_name=_("Delete"),
         text=_("Delete"),
     )
+
+
+class RegistrationStatesTable(tables.Table):
+    class Meta:
+        attrs = {"class": "responsive-table highlight"}
+
+    name = tables.Column()
+
+    edit = tables.LinkColumn(
+        "edit_registration_state_by_pk",
+        args=[A("id")],
+        verbose_name=_("Edit"),
+        text=_("Edit"),
+    )
+
+    def render_name(self, value, record):
+        context = dict(state=record)
+        return render_to_string("paweljong/registration_state/chip.html", context)
diff --git a/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html b/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..4238fe2f1e0a2876f4bc3dd2e21007f550b03e53
--- /dev/null
+++ b/aleksis/apps/paweljong/templates/paweljong/event_registration/edit.html
@@ -0,0 +1,22 @@
+{% extends "core/base.html" %}
+{% load material_form i18n any_js %}
+
+{% block page_title %}{% blocktrans %}Edit registration{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Edit registration{% endblocktrans %}{% endblock %}
+
+{% block extra_head %}
+    {{ form.media.css }}
+    {% include_css "select2-materialize" %}
+{% endblock %}
+
+{% block content %}
+
+  <form method="post">
+    {% csrf_token %}
+    {% form form=form %}{% form %}
+    {% include "core/partials/save_button.html" %}
+  </form>
+  {% include_js "select2-materialize" %}
+  {{ form.media.js }}
+
+{% endblock %}
diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html
new file mode 100644
index 0000000000000000000000000000000000000000..91aa0ef0694bf36b42c4f2f904718aa4b5c02520
--- /dev/null
+++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/chip.html
@@ -0,0 +1,19 @@
+{# -*- engine:django -*- #}
+
+{% if states %}
+  {% for state in states %}
+    <div class="chip white-text" style="background-color: {{ state.colour|default:"black" }};">
+      {{ state }}
+      {% if small %}
+        <small>({{ small }})</small>
+      {% endif %}
+    </div>
+  {% endfor %}
+{% else %}
+  <div class="chip white-text" style="background-color: {{ state.colour|default:"black" }};">
+    {{ state.name }}
+    {% if small %}
+      <small>({{ small }})</small>
+    {% endif %}
+  </div>
+{% endif %}
diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html
new file mode 100644
index 0000000000000000000000000000000000000000..d8215a976213042538a433af65d2d68ef224319d
--- /dev/null
+++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/create.html
@@ -0,0 +1,19 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% block page_title %}{% blocktrans %}Create registration state{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Create registration state{% endblocktrans %}{% endblock %}
+
+{% block extra_head %}
+    {{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+  <form method="post">
+    {% csrf_token %}
+    {% form form=form %}{% endform %}
+    {% include "core/partials/save_button.html" %}
+  </form>
+
+  {{ form.media.js }}
+{% endblock %}
diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..da8ec67d9060ac6460c0f9477111d8c684b40b0c
--- /dev/null
+++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/edit.html
@@ -0,0 +1,18 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% block page_title %}{% blocktrans %}Edit registration state{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Edit registration state{% endblocktrans %}{% endblock %}
+
+{% block extra_head %}
+    {{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+  <form method="post">
+    {% csrf_token %}
+    {% form form=form %}{% endform %}
+    {% include "core/partials/save_button.html" %}
+  </form>
+  {{ form.media.js }}
+{% endblock %}
diff --git a/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html b/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..40771901ce17d65dfbc09a61917eb498dcca62c6
--- /dev/null
+++ b/aleksis/apps/paweljong/templates/paweljong/registration_state/list.html
@@ -0,0 +1,14 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% load render_table from django_tables2 %}
+
+{% block page_title %}{% blocktrans %}Registration states{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Registration states{% endblocktrans %}{% endblock %}
+
+{% block content %}
+
+    <a class="btn colour-primary waves-effect waves-light" href="{% url 'create_registration_state' %}">{% trans "Create registration state" %}</a>
+    {% render_table table %}
+
+{% endblock %}
diff --git a/aleksis/apps/paweljong/urls.py b/aleksis/apps/paweljong/urls.py
index d2a43fd5c9a994cdc33720944ea85d12b3ce79ce..5568600668fe34105b8ceb8f5df8b8f51ef1d0b0 100644
--- a/aleksis/apps/paweljong/urls.py
+++ b/aleksis/apps/paweljong/urls.py
@@ -107,6 +107,21 @@ urlpatterns = [
         views.TermEditView.as_view(),
         name="edit_term_by_pk",
     ),
+    path(
+        "event/registrations/states/list",
+        views.RegistrationStateListView.as_view(),
+        name="registration_states",
+    ),
+    path(
+        "event/registrations/states/create",
+        views.RegistrationStateCreateView.as_view(),
+        name="create_registration_state",
+    ),
+    path(
+        "event/registrations/states/<int:pk>/edit",
+        views.RegistrationStateEditView.as_view(),
+        name="edit_registration_state_by_pk",
+    ),
     path(
         "info_mailings/list",
         views.InfoMailingListView.as_view(),
diff --git a/aleksis/apps/paweljong/views.py b/aleksis/apps/paweljong/views.py
index 9786d3140eb75f828fe516c4f27ce29b47eb1e8c..a5251d9d11d11d929bcce83a385400f31c40513e 100644
--- a/aleksis/apps/paweljong/views.py
+++ b/aleksis/apps/paweljong/views.py
@@ -37,14 +37,16 @@ from .forms import (
     EditVoucherForm,
     GenerateListForm,
     RegistrationNotificationForm,
+    RegistrationStatesForm,
 )
-from .models import Event, EventRegistration, InfoMailing, Terms, Voucher
+from .models import Event, EventRegistration, InfoMailing, Terms, Voucher, RegistrationState
 from .tables import (
     EventRegistrationsTable,
     InfoMailingsTable,
     ManageEventsTable,
     TermsTable,
     VouchersTable,
+    RegistrationStatesTable,
 )
 
 User = get_user_model()
@@ -160,7 +162,7 @@ class EventRegistrationCreateView(PermissionRequiredMixin, AdvancedCreateView):
     form_class = EditEventRegistrationForm
     permission_required = "paweljong.manage_registration"
     template_name = "paweljong/event_registration/create.html"
-    success_url = reverse_lazy("event_registrations")
+    success_url = reverse_lazy("registrations")
     success_message = _("The event registration has been created.")
 
 
@@ -172,7 +174,7 @@ class EventRegistrationEditView(PermissionRequiredMixin, AdvancedEditView):
     form_class = EditEventRegistrationForm
     permission_required = "paweljong.manage_eventregistration"
     template_name = "paweljong/event_registration/edit.html"
-    success_url = reverse_lazy("event_registrations")
+    success_url = reverse_lazy("registrations")
     success_message = _("The event registration has been saved.")
 
 
@@ -860,3 +862,36 @@ class SendMailFromRegistration(PermissionRequiredMixin, FormView):
         )
 
         return super().form_valid(self)
+
+
+class RegistrationStateListView(PermissionRequiredMixin, SingleTableView):
+    """Table of all terms."""
+
+    model = RegistrationState
+    table_class = RegistrationStatesTable
+    permission_required = "paweljong.view_registration_states"
+    template_name = "paweljong/registration_state/list.html"
+
+
+@method_decorator(never_cache, name="dispatch")
+class RegistrationStateCreateView(PermissionRequiredMixin, AdvancedCreateView):
+    """Create view for terms."""
+
+    model = RegistrationState
+    form_class = RegistrationStatesForm
+    permission_required = "paweljong.add_registration_states"
+    template_name = "paweljong/registration_state/create.html"
+    success_url = reverse_lazy("registration_states")
+    success_message = _("The term has been created.")
+
+
+@method_decorator(never_cache, name="dispatch")
+class RegistrationStateEditView(PermissionRequiredMixin, AdvancedEditView):
+    """Edit view for terms."""
+
+    model = RegistrationState
+    form_class = RegistrationStatesForm
+    permission_required = "paweljong.edit_registration_states"
+    template_name = "paweljong/registration_state/edit.html"
+    success_url = reverse_lazy("registration_states")
+    success_message = _("The term has been saved.")