diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 5f825744bc9ff3fe9e3ebb52e80ac8f622480bb1..fe40b48d52b06b44bfd28b12722e96b5023eee39 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -15,6 +15,11 @@ Added
 * Add Ukrainian locale (contributed by Sergiy Gorichenko from Fre(i)e Software GmbH).
 * Add third gender to gender choices
 
+Changed
+~~~~~~~
+
+* Restructure group page and show more information about members.
+
 Fixed
 ~~~~~~~
 
diff --git a/aleksis/core/static/public/style.scss b/aleksis/core/static/public/style.scss
index 4ae42c291d77c2dddfb3550dc454a0b78a188da4..7aaff6575cbd675a891944a6767291854cc76f78 100644
--- a/aleksis/core/static/public/style.scss
+++ b/aleksis/core/static/public/style.scss
@@ -990,3 +990,8 @@ p.ical-description {
   margin: 0;
   font-weight: 300;
 }
+
+.table-circle, .table-circle .materialize-circle {
+  height: 4em;
+  width: 4em;
+}
diff --git a/aleksis/core/tables.py b/aleksis/core/tables.py
index f08460bd8654907cb56f655e01014342f8e59ab5..d60b691c2abc995e00d2b66c39e9ca35f641fe87 100644
--- a/aleksis/core/tables.py
+++ b/aleksis/core/tables.py
@@ -1,5 +1,6 @@
 from textwrap import wrap
 
+from django.template.loader import render_to_string
 from django.utils.translation import gettext_lazy as _
 
 import django_tables2 as tables
@@ -31,12 +32,57 @@ class PersonsTable(tables.Table):
     """Table to list persons."""
 
     class Meta:
+        model = Person
         attrs = {"class": "highlight"}
+        fields = []
 
     first_name = tables.LinkColumn("person_by_id", args=[A("id")])
     last_name = tables.LinkColumn("person_by_id", args=[A("id")])
 
 
+class FullPersonsTable(PersonsTable):
+    """Table to list persons."""
+
+    photo = tables.Column(verbose_name=_("Photo"), accessor="pk", orderable=False)
+
+    class Meta(PersonsTable.Meta):
+        fields = (
+            "photo",
+            "date_of_birth",
+            "sex",
+            "email",
+            "street",
+            "housenumber",
+            "postal_code",
+            "place",
+        )
+        sequence = ("photo", "first_name", "last_name", "...")
+
+    def render_photo(self, value, record):
+        return render_to_string(
+            "core/partials/avatar_content.html",
+            {
+                "person_or_user": record,
+                "class": "materialize-circle table-circle",
+                "img_class": "materialize-circle",
+            },
+            self.request,
+        )
+
+    def before_render(self, request):
+        """Hide columns if user has no permission to view them."""
+        if not self.request.user.has_perm("core.view_person_rule"):
+            self.columns.hide("date_of_birth")
+            self.columns.hide("sex")
+        if not self.request.user.has_perm("core.view_contact_details_rule"):
+            self.columns.hide("email")
+        if not self.request.user.has_perm("core.view_address"):
+            self.columns.hide("street")
+            self.columns.hide("housenumber")
+            self.columns.hide("postal_code")
+            self.columns.hide("place")
+
+
 class GroupsTable(tables.Table):
     """Table to list groups."""
 
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 62ac22aa692ad5075ead9cf0d0bdd139f2fbccaf..2a501d52bbe0e3a4e61a0d0e7d0d5c1438be6a25 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -115,6 +115,7 @@ from .registries import (
 from .tables import (
     AdditionalFieldsTable,
     DashboardWidgetTable,
+    FullPersonsTable,
     GroupGlobalPermissionTable,
     GroupObjectPermissionTable,
     GroupsTable,
@@ -358,7 +359,7 @@ def group(request: HttpRequest, id_: int) -> HttpResponse:
     members = group.members.all()
 
     # Build table
-    members_table = PersonsTable(members)
+    members_table = FullPersonsTable(members)
     RequestConfig(request).configure(members_table)
     context["members_table"] = members_table