diff --git a/Gemfile b/Gemfile
index 4717b9b16532d4a2ae157e1ddcad4cade2dab9d4..1ea23427d44a8b8458ccbf432e43d38c1f8f5995 100644
--- a/Gemfile
+++ b/Gemfile
@@ -65,3 +65,5 @@ gem "tailwindcss-rails", "~> 2.6"
 gem "hotwire-rails", "~> 0.1.3"
 
 gem "importmap-rails", "~> 2.0"
+
+gem "icalendar", "~> 2.10"
diff --git a/Gemfile.lock b/Gemfile.lock
index a07fabb1b1449192b9db3d215e5a0f70c3d70bac..a26ea99158d1fb0b582fc63e67a9e13d83de6ad3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -117,6 +117,9 @@ GEM
       multi_xml (>= 0.5.2)
     i18n (1.14.4)
       concurrent-ruby (~> 1.0)
+    icalendar (2.10.1)
+      ice_cube (~> 0.16)
+    ice_cube (0.16.4)
     importmap-rails (2.0.1)
       actionpack (>= 6.0.0)
       activesupport (>= 6.0.0)
@@ -272,6 +275,7 @@ GEM
 PLATFORMS
   aarch64-linux
   arm64-darwin-22
+  arm64-darwin-23
   x86_64-linux
 
 DEPENDENCIES
@@ -280,6 +284,7 @@ DEPENDENCIES
   debug
   hotwire-rails (~> 0.1.3)
   httparty
+  icalendar (~> 2.10)
   importmap-rails (~> 2.0)
   jbuilder
   puma (>= 5.0)
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index e5808c2e6bfab562421ce6ed42f31dabdd94d2a7..525f70c8840ead7e648435893af2a1b8eea6ef10 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -14,9 +14,6 @@
  *= require_self
  */
 /* Add your styles here to layout the tabs, timeline, and session blocks */
-* {
-  box-sizing: border-box;
-}
 
 .timeline {
   position: relative;
@@ -47,9 +44,6 @@
 }
 .stage-sessions {
   position: relative;
-}
-.times {
-
 }
 .time {
   border-top: 1px dotted gray;
diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css
index 6f2068570f6bc5e69f5d47e317a7f98d8f035355..9c0e8aa5f34d81b1bb44c1ae34ccb8c21c227bc3 100644
--- a/app/assets/stylesheets/application.tailwind.css
+++ b/app/assets/stylesheets/application.tailwind.css
@@ -15,7 +15,7 @@
 h1, h2, h3, h4, h5, h6 {
   @apply font-bold;
 }
-input[type=submit], button {
+input[type=submit] {
   @apply border rounded-md px-2 py-1;
   &.primary {
     @apply bg-teal-800 text-teal-50;
diff --git a/app/controllers/assignments_controller.rb b/app/controllers/assignments_controller.rb
index aa3062582ee70fb775fa688e24632c315b4ec478..e0ff578b72ac173c167ddbfc43075f517630852a 100644
--- a/app/controllers/assignments_controller.rb
+++ b/app/controllers/assignments_controller.rb
@@ -9,22 +9,70 @@ class AssignmentsController < ApplicationController
   end
 
   def create
+    @session = Session.find_by(ref_id: params[:session_ref_id])
+    @conference = Conference.find_by(slug: params[:conference_slug])
     @user = User.find(params[:user_id])
     @assignment = @session.assignments.new(user: @user)
 
     if @assignment.save
-      redirect_to @session, notice: "User was successfully assigned to session."
+      flash.now[:success] = 'User assigned successfully.'
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }) }
+        format.html { redirect_to conference_session_path(@session.conference, @session), success: 'User assigned successfully.' }
+      end
     else
-      flash[:alert] = @assignment.errors.full_messages.join(", ")
-      render 'sessions/show'
+      flash.now[:alert] = 'Failed to assign user.'
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }), status: :unprocessable_entity }
+        format.html { render :show, status: :unprocessable_entity }
+      end
     end
   end
 
   def destroy
-    @assignment = @session.assignments.find_by(user_id: params[:user_id])
-    @assignment.destroy
+    @assignment = Assignment.find(params[:id])
+    @session = @assignment.session
+
+    if @assignment&.destroy
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }) }
+        format.html { redirect_to conference_session_path(@session.conference, @session), notice: 'User removed successfully.' }
+      end
+    else
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(@session), partial: "sessions/session", locals: { session: @session }), status: :unprocessable_entity }
+        format.html { redirect_to conference_session_path(@session.conference, @session), alert: 'Failed to remove user.' }
+      end
+    end
+  end
+
+  def by_user
+    @user = User.includes(:assignments).find(params[:user_id])
     respond_to do |format|
-      format.html { redirect_to @session, notice: "User assignment removed successfully." }
+      format.html # This will render the existing HTML view (assignments/by_user.html.erb)
+
+      format.ics do
+        calendar = Icalendar::Calendar.new
+
+        @user.assignments.each do |assignment|
+          session = assignment.session
+
+          event = Icalendar::Event.new
+          event.dtstart = Icalendar::Values::DateTime.new(session.starts_at, tzid: session.starts_at.zone)
+          event.dtend = Icalendar::Values::DateTime.new(session.ends_at, tzid: session.ends_at.zone)
+          event.summary = session.title
+          event.description = session.description
+          event.location = [session.stage.name, session.conference.name].join(' @ ')
+          event.created = Icalendar::Values::DateTime.new(session.created_at)
+          event.last_modified = Icalendar::Values::DateTime.new(session.updated_at)
+          event.uid = [session.conference.slug, session.ref_id].join('-')
+          calendar.add_event(event)
+        end
+
+        calendar.publish
+        headers['Content-Type'] = 'text/calendar; charset=UTF-8'
+        render plain: calendar.to_ical
+      end
     end
   end
 
diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb
index 038e5903b44193d0af9e09a34410cd2454bfc5da..4077705f6c6a7d2ccdae22628ac1581bc57d51cb 100644
--- a/app/controllers/conferences_controller.rb
+++ b/app/controllers/conferences_controller.rb
@@ -5,8 +5,7 @@ class ConferencesController < ApplicationController
 
   def show
     @conference = Conference.find_by(slug: params[:slug])
-    @sessions = @conference.sessions.where.not(starts_at: nil).includes(:stage).order(:starts_at)
-    @sessions_by_date = @sessions.group_by{ |x| x.starts_at.to_date }
+    @sessions = @conference.sessions.where.not(starts_at: nil).includes(:stage, :assignments).where(stage: { name: ["Stage 1", "Stage 2"] }).order(:starts_at)
     @users = User.all
   end
 end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 5f107b097892485cbbb6052bac926a8008030df0..2feb7efa69a0e4b820a4f2ca79a63fc61ab5111b 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -22,38 +22,4 @@ class SessionsController < ApplicationController
     @session = Session.includes(:stage).find_by(ref_id: params[:ref_id])
     @users = User.all
   end
-
-  def assign_user
-    @session = Session.find_by(ref_id: params[:ref_id])
-    @conference = Conference.find_by(slug: params[:slug])
-    @user = User.find(params[:user_id])
-    @assignment = @session.assignments.new(session: @session, user: @user)
-    @users = User.all
-
-    if @assignment.save
-      flash.now[:success] = 'User assigned successfully.'
-      respond_to do |format|
-        # format.turbo_stream
-        format.html { redirect_to conference_session_path(@session.conference, @session), success: 'User assigned successfully.' }
-      end
-    else
-      flash.now[:alert] = 'Failed to assign user.'
-      respond_to do |format|
-        # format.turbo_stream { render :show, status: :unprocessable_entity }
-        format.html { render :show, status: :unprocessable_entity, alert: 'Failed to assign user.' }
-      end
-    end
-  end
-
-  def unassign_user
-    @session = Session.find_by(ref_id: params[:ref_id])
-    @user = User.find(params[:user_id])
-    @assignment = Assignment.find_by(session: @session, user: @user)
-
-    if @assignment&.destroy
-      redirect_to conference_session_path(@session.conference, @session), notice: 'User removed successfully.'
-    else
-      redirect_to conference_session_path(@session.conference, @session), alert: 'Failed to remove user.'
-    end
-  end
 end
diff --git a/app/jobs/republica_2023_or_later/import_job.rb b/app/jobs/republica_2023_or_later/import_job.rb
index 2c3b54250c56e273ad88ab9df7824eb401c41576..4d2087043340bc14cf0bb4e09ef4ff7efba98da3 100644
--- a/app/jobs/republica_2023_or_later/import_job.rb
+++ b/app/jobs/republica_2023_or_later/import_job.rb
@@ -25,7 +25,7 @@ module Republica2023OrLater
               end
             session.status = session_data['status']
             session.description = session_data['description']
-            session.format = session_data['format']
+            session.session_format = session_data['format']
             session.track = session_data['track']
             session.is_interpreted = (session_data['live_translation'] == "1")
             session.starts_at = session_data['datetime_start']
diff --git a/app/models/conference.rb b/app/models/conference.rb
index 40b40a551f68f9104764dd76c72882b6f9b35639..a4efb3d051d584206491bdc3d7e7085a66d09bff 100644
--- a/app/models/conference.rb
+++ b/app/models/conference.rb
@@ -1,8 +1,11 @@
 class Conference < ApplicationRecord
   has_many :sessions
   has_many :stages
+
   serialize :data, coder: JSON
 
+  validates :time_zone, presence: true, inclusion: { in: ActiveSupport::TimeZone.all.map(&:name) }
+
   def days
     (starts_at.to_date..ends_at.to_date)
   end
@@ -10,4 +13,12 @@ class Conference < ApplicationRecord
   def to_param
     slug
   end
+
+  def starts_at_in_local_time
+    starts_at.in_time_zone(time_zone || 'UTC')
+  end
+
+  def ends_at_in_local_time
+    ends_at.in_time_zone(time_zone || 'UTC')
+  end
 end
diff --git a/app/models/session.rb b/app/models/session.rb
index 6a18ee751259d3064d9d318f6441cfaa2cf656c3..1a757bdfc3a61bbec2ef8e50cc845d18c6e8006e 100644
--- a/app/models/session.rb
+++ b/app/models/session.rb
@@ -9,4 +9,12 @@ class Session < ApplicationRecord
   def to_param
     ref_id
   end
+
+  def starts_at
+    super.in_time_zone(conference.time_zone)
+  end
+
+  def ends_at
+    super.in_time_zone(conference.time_zone)
+  end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index 429f19a9aa993a2cf4d046c46028ed9bde503832..8e3dc5ad13a7f4a5ac47d34ae4fc63f0c70c8b7b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,7 @@
 class User < ApplicationRecord
+  has_many :assignments
+  validates :email, uniqueness: { case_sensitive: false, message: "already in use" }
+
   after_initialize :set_avatar_color
 
   def text_color
diff --git a/app/views/application/_user_avatar.html.erb b/app/views/application/_user_avatar.html.erb
index ff2f9b420ac3cd07e337796ef4c4d03a43d4333b..6e26c21f4f484cfa3e7ca7400dbcf09fd5481a2e 100644
--- a/app/views/application/_user_avatar.html.erb
+++ b/app/views/application/_user_avatar.html.erb
@@ -1,3 +1,3 @@
-<div class="relative inline-flex items-center justify-center h-8 p-2 overflow-hidden rounded-full" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
-    <span class="font-medium" style="color: <%= user.text_color %>"><%= user.name %></span>
-</div>
+<span class="inline-flex items-center gap-x-0.5 rounded-full bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
+  <span style="color: <%= user.text_color %>"><%= user.name.split(/\s+/).map(&:first).join('') %></span>
+</span>
diff --git a/app/views/assignments/_user_avatar.html.erb b/app/views/assignments/_user_avatar.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8f1cc9b938307ce8705c82ca4ce420b8939ff7a6
--- /dev/null
+++ b/app/views/assignments/_user_avatar.html.erb
@@ -0,0 +1,13 @@
+<% user = assignment.user %>
+<span class="inline-flex items-center gap-x-0.5 rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
+  <span style="color: <%= user.text_color %>"><%= user.name %></span>
+  <button type="button" class="group relative -mr-1 size-3.5 rounded-sm hover:bg-gray-500/20">
+    <%= link_to conference_session_assignment_path(assignment.session.conference, assignment.session, assignment), data: { turbo_method: :delete, confirm: 'Are you sure?' }, method: :delete do %>
+      <span class="sr-only">Remove</span>
+      <svg viewBox="0 0 14 14" class="size-3.5 stroke-gray-600/50 group-hover:stroke-gray-600/75" style="stroke: <%= user.text_color %>">
+        <path d="M4 4l6 6m0-6l-6 6" />
+      </svg>
+      <span class="absolute -inset-1"></span>
+    <% end %>
+  </button>
+</span>
diff --git a/app/views/assignments/by_user.html.erb b/app/views/assignments/by_user.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..9014b7f72ecef1e0d3d1ca16d75c8c1a9544a587
--- /dev/null
+++ b/app/views/assignments/by_user.html.erb
@@ -0,0 +1,10 @@
+<ul>
+  <% @user.assignments.includes(:session, session: :conference).order('sessions.starts_at').each do |assignment| %>
+    <li>
+      <%= assignment.session.conference.name %>
+      <%= assignment.session.starts_at %>
+      <%= assignment.session.stage.name %>
+      <%= assignment.session.title %>
+    </li>
+  <% end %>
+</ul>
\ No newline at end of file
diff --git a/app/views/conferences/show.html.erb b/app/views/conferences/show.html.erb
index 8cba38aa8ad49e24c064e1d39cfbef7f33c98e7d..00b8cd4d034d0a286922ee4e0fa0cd7f53ace3ef 100644
--- a/app/views/conferences/show.html.erb
+++ b/app/views/conferences/show.html.erb
@@ -2,12 +2,13 @@
 pixels_per_hour = 300.0
 timeline_granularity = 15
 # current_time = Time.zone.now
-current_time = @sessions_by_date[@conference.days.first].first.starts_at.advance(minutes: 5)
+current_time = Time.parse(@conference.days.first.strftime("%Y-%m-%d 10:37"))
+#current_time = @sessions_by_date[@conference.days.first].first.starts_at.advance(minutes: 5)
 %>
 <div>
-  <h1><%= @conference.name %></h1>
+  <h1 class="text-2xl font-bold my-6"><%= @conference.name %></h1>
 
-  <nav id="conference-days">
+  <nav id="conference-days" class="list-disc list-inside">
     <% @conference.days.each do |date| %>
       <li><%= link_to date.strftime("%Y-%m-%d"), "\##{date.strftime('day-%Y-%m-%d')}" %></li>
     <% end %>
@@ -15,21 +16,22 @@ current_time = @sessions_by_date[@conference.days.first].first.starts_at.advance
 
   <%
   @conference.days.each do |date|
+    @sessions_by_date = @sessions.group_by { |x| x.starts_at.to_date }
+    @sessions_by_date_and_stage = @sessions_by_date.transform_values{ |sessions| sessions.group_by { |s| s.stage } }
     day_starts_at = @sessions_by_date[date].first.starts_at
     day_ends_at = @sessions_by_date[date].last.ends_at
     # round to previous interval
-    timeline_starts_at = day_starts_at.beginning_of_hour.advance(minutes: (day_starts_at.min / timeline_granularity.to_f).floor * timeline_granularity)
+    timeline_starts_at = day_starts_at.advance(minutes: (day_starts_at.min / timeline_granularity.to_f).floor * timeline_granularity * -0.5)
     # ... , except rounding up to later interval
-    timeline_ends_at = day_ends_at.beginning_of_hour.advance(minutes: (day_ends_at.min / timeline_granularity.to_f).ceil * timeline_granularity)
+    timeline_ends_at = day_ends_at.advance(minutes: (day_ends_at.min / timeline_granularity.to_f).ceil * timeline_granularity)
   %>
-  <div class="conference-day" id="<%= date.strftime('day-%Y-%m-%d') %>" style="position: relative">
-    <h3><%= date.strftime('%B %d, %Y') %></h3>
-    <div class="day-wrapper flex" style="display: flex;">
+    <div class="conference-day my-8" id="<%= date.strftime('day-%Y-%m-%d') %>">
+      <h3 class="text-xl my-4 border-b"><%= date.strftime('%B %d, %Y') %></h3>
+      <div class="day-wrapper flex relative">
 
       <div class="times" style="">
         <h4>Time</h4>
-        <%
-        if current_time.strftime('%Y%m%d') == date.strftime('%Y%m%d')
+        <% if current_time.strftime('%Y%m%d') == date.strftime('%Y%m%d')
         %>
         <div class="current-time" style="top: <%= (current_time - timeline_starts_at) / 3600.0 * pixels_per_hour %>px"></div>
         <%
@@ -45,33 +47,23 @@ current_time = @sessions_by_date[@conference.days.first].first.starts_at.advance
         end
         %>
       </div>
+
       <div class="stages">
-      <% @sessions_by_date[date].group_by(&:stage).each do |stage, sessions| %>
-        <% next unless ["Stage 1", "Stage 2"].include? stage.name %>
-        <div class="stage">
-          <h4><%= stage.name %></h4>
-          <div class="stage-sessions">
-          <% sessions.each do |session| %>
-            <div class="session" style="position: absolute; top: <%= (session.starts_at - timeline_starts_at) / 3600.0 * pixels_per_hour %>px; height: <%= (session.ends_at - session.starts_at) / 3600.0 * pixels_per_hour%>px; overflow: scroll;">
-              <h4><%= link_to session.title, [@conference, session] %></h4>
-              <p class="session-time"><%= session.starts_at.strftime('%H:%M') %> - <%= session.ends_at.strftime('%H:%M') %></p>
-              <%#<div class="session-desc"><%= session.description.html_safe %><%#/div>%>
-              <ul class="list-disc">
-                <% session.assignments.each do |assignment| %>
-                  <li>
-                    <span class="assigned-user"><%= render partial: 'application/user_avatar', locals: { user: assignment.user } %></span>
-                    <%= link_to '[Remove]', conference_session_assignments_path(session.conference, session, user_id: assignment.user_id), data: { turbo_method: :delete, confirm: 'Are you sure?' } %>
-                  </li>
-                <% end %>
-              </ul>
-              <%= render partial: "sessions/assignment_form", locals: { session: session } %>
+
+        <% @sessions_by_date_and_stage[date].each do |stage, sessions| %>
+          <div class="stage">
+            <h4><%= stage.name %></h4>
+            <div class="stage-sessions">
+              <% sessions.each do |session| %>
+                <div class="session text-sm" style="position: absolute; top: <%= (session.starts_at - timeline_starts_at) / 3600.0 * pixels_per_hour %>px; height: <%= (session.ends_at - session.starts_at) / 3600.0 * pixels_per_hour %>px; overflow: scroll;">
+                  <%= render partial: "sessions/session", locals: { session: session } %>
+                </div>
+              <% end %>
             </div>
-          <% end %>
           </div>
-        </div>
-      <% end %>
+        <% end %>
       </div>
     </div>
   </div>
   <% end %>
-</div>
+</div>
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 9f79c2f38b69d91c34b45ed70fdeae02cdfdee1e..d8c668001681d5160e73b74dc47df15b8ee6bb3e 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -12,7 +12,7 @@
   </head>
 
   <body>
-    <main class="container mx-auto mt-28 px-5 flex">
+    <main class="container mx-auto mt-8 px-5 flex">
       <%= yield %>
     </main>
   </body>
diff --git a/app/views/sessions/_assignment_form.html.erb b/app/views/sessions/_assignment_form.html.erb
index d9a4d98e4c91f9637464cc9cec38541d16c42126..45ce934288ea20de4095bebe55217ed18fadcc45 100644
--- a/app/views/sessions/_assignment_form.html.erb
+++ b/app/views/sessions/_assignment_form.html.erb
@@ -1,9 +1,12 @@
-<%= form_with url: conference_session_assignments_path(session.conference, session), method: :post, local: true do |f| %>
-  <%= f.select :user_id, options_from_collection_for_select(@users - session.assignments.collect(&:user), :id, :name) %>
-  <%= f.submit "Assign", class: 'primary' %>
-  <% if @assignment&.errors&.any? %>
-    <div class="alert alert-danger">
-      <%= @assignment.errors.full_messages.join(", ") %>
-    </div>
+<% unassigned_users = @users - session.assignments.collect(&:user) %>
+<% if unassigned_users.length > 0 %>
+  <%= form_with url: conference_session_assignments_path(session.conference, session), method: :post, data: { turbo_frame: dom_id(session) } do |f| %>
+    <%= f.select :user_id, options_from_collection_for_select(unassigned_users, :id, :name) %>
+    <%= f.submit "Assign", class: 'primary' %>
+    <% if @assignment&.errors&.any? %>
+      <div class="alert alert-danger">
+        <%= @assignment.errors.full_messages.join(", ") %>
+      </div>
+    <% end %>
   <% end %>
 <% end %>
diff --git a/app/views/sessions/_session.html.erb b/app/views/sessions/_session.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..1f03f318f1b0be03f27fa0692f40233df535b025
--- /dev/null
+++ b/app/views/sessions/_session.html.erb
@@ -0,0 +1,12 @@
+<%= turbo_frame_tag dom_id(session) do %>
+  <h4><%= link_to session.title, [session.conference, session], target: "_top" %></h4>
+  <p class="session-time"><%= session.starts_at.strftime('%H:%M') %> - <%= session.ends_at.strftime('%H:%M') %></p>
+  <ul class="inline-flex flex-wrap gap-1 my-1">
+    <% session.assignments.each do |assignment| %>
+      <li>
+        <span class="assigned-user"><%= render partial: 'assignments/user_avatar', locals: { assignment: assignment } %></span>
+      </li>
+    <% end %>
+  </ul>
+  <%= render partial: "sessions/assignment_form", locals: { session: session } %>
+<% end %>
diff --git a/app/views/sessions/show.html.erb b/app/views/sessions/show.html.erb
index e98f4221a8797696945dae3ecb2982efe9820b77..58d3a868f4e4e0e3ba6452dd4c4fb19927c95da4 100644
--- a/app/views/sessions/show.html.erb
+++ b/app/views/sessions/show.html.erb
@@ -1,5 +1,5 @@
 <div>
-  <h6><%= @session.conference.name %></h6>
+  <h6><%= link_to @session.conference.name, @session.conference %></h6>
   <h1><%= @session.title %></h1>
   <h2><%= @session.language %> <%= @session.is_interpreted ? "(live interpretation)" : "" %></h2>
   <h2><%= @session.starts_at.strftime("%Y-%m-%d") %> <%= @session.starts_at.strftime("%H:%M") %> &ndash; <%= @session.ends_at.strftime("%H:%M") %></h2>
@@ -7,11 +7,10 @@
   <p><%= @session.description.html_safe %></p>
   
   <h3>Assigned Users</h3>
-  <ul>
+  <ul class="inline-flex flex-wrap gap-1 my-1">
     <% @session.assignments.each do |assignment| %>
       <li>
-        <%= render partial: 'application/user_avatar', locals: { user: assignment.user } %>
-        <%= link_to '[Remove]', conference_session_assignments_path(@session.conference, @session, user_id: assignment.user_id), data: { turbo_method: :delete, confirm: 'Are you sure?' } %>
+        <span class="assigned-user"><%= render partial: 'assignments/user_avatar', locals: { assignment: assignment } %></span>
       </li>
     <% end %>
   </ul>
diff --git a/config/routes.rb b/config/routes.rb
index ffe5506ce24f282aacc18c3491d37d141443e497..ead8585fe56966fe6a4b62a9b5582b127d363176 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -11,11 +11,13 @@ Rails.application.routes.draw do
 
   resources :conferences, param: :slug do
     resources :sessions, param: :ref_id do
-      resource :assignments, only: [:create, :destroy]
+      resources :assignments, only: [:create, :destroy]
     end
   end
 
-  resources :assignments, only: [:index]
+  resources :assignments, only: [:index] do
+    get 'for/:user_id', action: 'by_user', on: :collection
+  end
   resources :sessions, param: :ref_id
 
   # get 'conferences/:slug', to: 'conferences#show', as: :conference
diff --git a/db/migrate/20240525190720_add_time_zone_to_conference.rb b/db/migrate/20240525190720_add_time_zone_to_conference.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9436332578d83a06fae684f950769e3dae9aa7b5
--- /dev/null
+++ b/db/migrate/20240525190720_add_time_zone_to_conference.rb
@@ -0,0 +1,5 @@
+class AddTimeZoneToConference < ActiveRecord::Migration[7.1]
+  def change
+    add_column :conferences, :time_zone, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 322e2d2d508f6c815cb8d4362c4c29a3331ec001..b6e8e040c5b909c1953df3116c89ab1c8f9dc2a5 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.1].define(version: 2024_05_24_124124) do
+ActiveRecord::Schema[7.1].define(version: 2024_05_25_190720) do
   create_table "assignments", force: :cascade do |t|
     t.integer "user_id", null: false
     t.integer "session_id", null: false
@@ -32,6 +32,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_24_124124) do
     t.text "data"
     t.string "slug"
     t.string "import_job_class"
+    t.string "time_zone"
   end
 
   create_table "sessions", force: :cascade do |t|
diff --git a/db/seeds.rb b/db/seeds.rb
index 20d6c022a15ef4320fa9302e23d47dc8e1b426a5..cf19d0f70be37fcb3a923399aa57db471c2e2709 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -17,6 +17,7 @@ Conference.find_or_create_by!(slug: "rp2023") do |c|
     "sessions_url" => "https://re-publica.com/sites/default/files/extappdata/2023/session.json"
   }
   c.import_job_class = "republica_2023_or_later"
+  c.time_zone = "Berlin"
 end
 
 Conference.find_or_create_by!(slug: "rp2024") do |c|
@@ -28,9 +29,9 @@ Conference.find_or_create_by!(slug: "rp2024") do |c|
     "sessions_url" => "https://re-publica.com/sites/default/files/extappdata/2024/session.json"
   }
   c.import_job_class = "republica_2023_or_later"
+  c.time_zone = "Berlin"
 end
 
-User.find_or_create_by!(email: "teal@teal.is") do |user|
-  user.name = "Teal"
-  user.avatar_color = "#14bfb5"
+%w[Teal hdsjulian Sophie bergpiratin sblsg Max aerowaffle ningwie Senana ToniHDS].each do |username|
+  User.find_or_create_by!(name: username, email: "c3lingo+#{username}@x.moeffju.net")
 end