diff --git a/.gitignore b/.gitignore
index 33687b8235f99519db5d1a665f0488a6b3274cea..e06f8dbd963dde805c2ee4be219a32cd4d0deacd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ webpack-stats.json
 staticfiles
 node_modules
 shared/static/shared/*.{js,css,txt}
+media/*
diff --git a/lectures/templates/lectures/view_groups.html b/lectures/templates/lectures/view_groups.html
index f8daac40fb170d81583cee0770dca96a77abd021..c6f8da33a55b824fa3fcac2331e7806eec895ede 100644
--- a/lectures/templates/lectures/view_groups.html
+++ b/lectures/templates/lectures/view_groups.html
@@ -11,7 +11,7 @@
     <ul class="grid grid-cols-2 gap-3">
         {% for group in lecture_groups %}
             <li>
-                <a href="{% url "lectures:view_lectures" group.id %}" class="hover:no-underline">
+                <a href="{% url "lectures:view_lecture_index" group.id %}" class="hover:no-underline">
                     <div class="card elevation-6">
                         <div class="card__body hover:bg-gray-100 duration-100">
                             <h2 class="head-alt-sm">{{ group.name }}</h2>
diff --git a/lectures/templates/lectures/view_lecture_index.html b/lectures/templates/lectures/view_lecture_index.html
index cc1f9284ebc0639dc6702107e9c279caa8b4744a..113837f63fc7a097a23ba7208e3247341813c37c 100644
--- a/lectures/templates/lectures/view_lecture_index.html
+++ b/lectures/templates/lectures/view_lecture_index.html
@@ -60,7 +60,9 @@
                     </ul>
                 </template>
                 <template v-if="isCurrentView('calendar')">
-                    b
+                    <div class="__js-root">
+                        <ui-person-calendar events='[]'></ui-person-calendar>
+                    </div>
                 </template>
                 <template v-if="isCurrentView('recordings')">
                     c
diff --git a/lectures/views.py b/lectures/views.py
index 8f1e8b6cb25ba2a45eeb5607bf676819c72b4fc6..2ae4f259b7cd48166d821fee4a0018bb93253770 100644
--- a/lectures/views.py
+++ b/lectures/views.py
@@ -16,7 +16,10 @@ def get_base_context(request) -> dict:
 def view_avilable_groups(request):
     lecture_groups = (
         get_objects_for_user(request.user, "lectures.view_lecturegroup")
-        .filter(user_groups__in=request.user.groups.all())
+        .filter(
+            models.Q(user_groups__in=request.user.groups.all())
+            | models.Q(user_groups=None)
+        )
         .distinct()
         .all()
     )
diff --git a/media/364D1F51-B67A-4FA5-83E6-1F32D62B6A78.gif b/media/364D1F51-B67A-4FA5-83E6-1F32D62B6A78.gif
deleted file mode 100644
index 676aff60c51e1b4301828c99f241174cf3b7ab71..0000000000000000000000000000000000000000
Binary files a/media/364D1F51-B67A-4FA5-83E6-1F32D62B6A78.gif and /dev/null differ
diff --git a/package-lock.json b/package-lock.json
index 08fec9191c63a488b098c09adeca6d790146546c..84a39cdbf1ea9edbf4492c3bdbca828bf388afda 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
       "version": "0.0.1",
       "license": "AGPL-3.0-or-later",
       "dependencies": {
+        "@fullcalendar/core": "^6.1.6",
         "@tailwindcss/typography": "^0.5.9",
         "css-loader": "^6.7.3",
         "jquery": "^3.6.3",
@@ -40,6 +41,14 @@
         "node": ">=10.0.0"
       }
     },
+    "node_modules/@fullcalendar/core": {
+      "version": "6.1.6",
+      "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.6.tgz",
+      "integrity": "sha512-Q/3pWgOv7qr/eVpuDz+05jxJZSg7Fdwh4XgQP8DlJFLp5aLlOiiKdkTUIO1BX7clQtYTm8P0v7FqMKbsFiQInw==",
+      "dependencies": {
+        "preact": "~10.12.1"
+      }
+    },
     "node_modules/@jridgewell/gen-mapping": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@@ -1591,6 +1600,15 @@
       "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
       "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
     },
+    "node_modules/preact": {
+      "version": "10.12.1",
+      "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz",
+      "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/preact"
+      }
+    },
     "node_modules/punycode": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
diff --git a/package.json b/package.json
index 5b48e9878a2d5451c1f6d79ecaa994ee6da0ada8..4ec38d17f5c8d8d1172bbdc8e7d0464f9552b3fa 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
   "author": "Tomáš Valenta",
   "license": "AGPL-3.0-or-later",
   "dependencies": {
+    "@fullcalendar/core": "^6.1.6",
     "@tailwindcss/typography": "^0.5.9",
     "css-loader": "^6.7.3",
     "jquery": "^3.6.3",
diff --git a/shared/static/shared/style.css b/shared/static/shared/style.css
index 65506eabfd4d1bcaff1c6aea6f27d0705e463255..ab1bdd1332a26df209c637685145739a0f64a4a2 100644
--- a/shared/static/shared/style.css
+++ b/shared/static/shared/style.css
@@ -1025,10 +1025,6 @@ html {
   margin-bottom: 2.5rem;
 }
 
-.mb-12 {
-  margin-bottom: 3rem;
-}
-
 .mb-4 {
   margin-bottom: 1rem;
 }
@@ -1037,6 +1033,10 @@ html {
   margin-bottom: 1.5rem;
 }
 
+.mr-1 {
+  margin-right: 0.25rem;
+}
+
 .mt-4 {
   margin-top: 1rem;
 }
@@ -1073,6 +1073,10 @@ html {
   cursor: pointer;
 }
 
+.grid-cols-1 {
+  grid-template-columns: repeat(1, minmax(0, 1fr));
+}
+
 .grid-cols-2 {
   grid-template-columns: repeat(2, minmax(0, 1fr));
 }
@@ -1101,6 +1105,10 @@ html {
   gap: 0.75rem;
 }
 
+.gap-4 {
+  gap: 1rem;
+}
+
 .space-x-2 > :not([hidden]) ~ :not([hidden]) {
   --tw-space-x-reverse: 0;
   margin-right: calc(0.5rem * var(--tw-space-x-reverse));
@@ -1123,6 +1131,10 @@ html {
   align-self: flex-start;
 }
 
+.p-5 {
+  padding: 1.25rem;
+}
+
 .py-4 {
   padding-top: 1rem;
   padding-bottom: 1rem;
@@ -1231,6 +1243,10 @@ html {
     width: 10rem;
   }
 
+  .md\:grid-cols-2 {
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+  }
+
   .md\:flex-row {
     flex-direction: row;
   }
diff --git a/shared/templates/shared/includes/base.html b/shared/templates/shared/includes/base.html
index 01e27041967d3ebdb2021c65e7287c586c320f06..18663dbbdef61af14d0f7e265b051672e0919d66 100644
--- a/shared/templates/shared/includes/base.html
+++ b/shared/templates/shared/includes/base.html
@@ -192,7 +192,7 @@
         </footer>
 
         <script
-            src="https://styleguide.pirati.cz/2.11.x/js/main.bundle.js"
+            src="https://styleguide.pirati.cz/2.12.x/js/main.bundle.js"
         ></script>
     </body>
 </html>