From 9428ce5ec18a5cd05c5a215263956d4b4b2a5839 Mon Sep 17 00:00:00 2001
From: Kolya Opahle <k.opahle@sap.com>
Date: Wed, 16 Dec 2020 14:16:19 +0100
Subject: [PATCH] Contact Diary - Day edit screen (EXPOSUREAPP-4156) (#1833)

* Made ContactDiaryActivity launchable, also added the first set of Implementations for the day editor view and tabs

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Switched View Model to publish a single UIState data class

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added run configuration to launch contact diary activity

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* linting

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* linting

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added RecyclerViews for person and place tabs

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* linting

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Renamed Place to Location

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added background for empty location list

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added background for empty people list
Added dummy code to add person/location to repo

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Moved day edit tabs to their own subpackage
Added Resources to tab configuration instead of plain text

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* linting

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added night mode illustrations

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added ability to select person / place (hacky)

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added DispatcherProvider injection to viewmodels

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Updated dawables to match new design

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* moved layout manager assignment into the layout files

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Migrated Day edit screens to finished room impl

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added bottom sheets for person and location creation

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* linting

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Migrated Bottom Sheets to finished room impl

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added input size validation for person and location bottom sheet Changed date nav arg to string from long Updated layout of location and person list items

* linting

* Removed launch helpers as home fragment card is now introduced

* Separated the Contact Diary UI and Storage Modules to allow for more specific dependency graphs

* Moved Contact Diary Dagger Modules into own root module

* Moved most of the tab logic out of the view model into the fragment

* Picking up some merge slack

* Switched contact diary day view navigation to navigation events

* Cleaning up the onboarding fragment

* Cleaning up the overview fragment

* adding navigation to day fragment to overview fragment

* linting

* linting

* Fixed contact diary theming

* Changed tabs to sealed classes

Co-authored-by: Matthias Urhahn <matthias.urhahn@sap.com>
---
 Corona-Warn-App/src/main/AndroidManifest.xml  |  2 +-
 .../contactdiary/ContactDiaryModule.kt        |  9 --
 .../contactdiary/ContactDiaryRootModule.kt    | 17 ++++
 .../model/ContactDiaryLocation.kt             |  4 +-
 .../contactdiary/model/ContactDiaryPerson.kt  |  4 +-
 .../model/DefaultContactDiaryLocation.kt      |  6 --
 .../model/DefaultContactDiaryPerson.kt        |  6 --
 .../entity/ContactDiaryLocationEntity.kt      |  5 +-
 .../entity/ContactDiaryPersonEntity.kt        |  5 +-
 .../repo/DefaultContactDiaryRepository.kt     |  6 +-
 .../contactdiary/ui/ContactDiaryModule.kt     | 17 ----
 .../contactdiary/ui/ContactDiaryUIModule.kt   | 42 ++++++++++
 .../ui/day/ContactDiaryDayFragment.kt         | 82 +++++++++++++++++++
 .../ui/day/ContactDiaryDayModule.kt           | 18 ++++
 .../ui/day/ContactDiaryDayNavigationEvents.kt |  7 ++
 .../ui/day/ContactDiaryDayViewModel.kt        | 53 ++++++++++++
 ...tDiaryLocationBottomSheetDialogFragment.kt | 57 +++++++++++++
 ...actDiaryLocationBottomSheetDialogModule.kt | 18 ++++
 ...DiaryLocationBottomSheetDialogViewModel.kt | 49 +++++++++++
 ...actDiaryPersonBottomSheetDialogFragment.kt | 57 +++++++++++++
 ...ntactDiaryPersonBottomSheetDialogModule.kt | 18 ++++
 ...ctDiaryPersonBottomSheetDialogViewModel.kt | 49 +++++++++++
 .../tabs/ContactDiaryDayFragmentsAdapter.kt   | 14 ++++
 .../ui/day/tabs/ContactDiaryDayTab.kt         | 36 ++++++++
 .../ContactDiaryLocationListAdapter.kt        | 52 ++++++++++++
 .../ContactDiaryLocationListFragment.kt       | 55 +++++++++++++
 .../ContactDiaryLocationListModule.kt         | 18 ++++
 .../ContactDiaryLocationListViewModel.kt      | 57 +++++++++++++
 .../person/ContactDiaryPersonListAdapter.kt   | 51 ++++++++++++
 .../person/ContactDiaryPersonListFragment.kt  | 55 +++++++++++++
 .../person/ContactDiaryPersonListModule.kt    | 18 ++++
 .../person/ContactDiaryPersonListViewModel.kt | 57 +++++++++++++
 .../ContactDiaryOnboardingFragment.kt         | 15 +---
 .../ContactDiaryOnboardingFragmentModul.kt    | 23 ------
 .../ContactDiaryOnboardingFragmentModule.kt   |  1 -
 .../ContactDiaryOnboardingNavigationEvents.kt |  1 -
 .../overview/ContactDiaryOverviewFragment.kt  | 12 ++-
 .../ContactDiaryOverviewFragmentModule.kt     |  5 --
 .../ui/overview/ContactDiaryOverviewMenu.kt   |  5 --
 .../ContactDiaryOverviewNavigationEvents.kt   |  1 -
 .../overview/ContactDiaryOverviewViewModel.kt |  1 -
 .../util/ContactDiaryExtensions.kt            | 11 +++
 .../util/MarginRecyclerViewDecoration.kt      | 23 ++++++
 .../contactdiary/util/SelectableItem.kt       |  9 ++
 .../de/rki/coronawarnapp/ui/ActivityBinder.kt |  5 --
 .../util/di/ApplicationComponent.kt           |  4 +-
 .../ic_illustration_no_locations.xml          | 23 ++++++
 .../ic_illustration_no_people.xml             | 75 +++++++++++++++++
 .../drawable/ic_illustration_no_locations.xml | 23 ++++++
 .../drawable/ic_illustration_no_people.xml    | 62 ++++++++++++++
 .../src/main/res/drawable/ic_selected.xml     | 10 +++
 .../src/main/res/drawable/ic_unselected.xml   | 11 +++
 .../res/layout/contact_diary_activity.xml     |  2 +-
 .../res/layout/contact_diary_day_fragment.xml | 52 ++++++++++++
 ...t_diary_location_bottom_sheet_fragment.xml | 65 +++++++++++++++
 .../contact_diary_location_list_fragment.xml  | 67 +++++++++++++++
 .../contact_diary_location_list_line.xml      | 34 ++++++++
 ...act_diary_person_bottom_sheet_fragment.xml | 65 +++++++++++++++
 .../contact_diary_person_list_fragment.xml    | 67 +++++++++++++++
 .../layout/contact_diary_person_list_line.xml | 34 ++++++++
 .../navigation/contact_diary_nav_graph.xml    | 47 ++++++++++-
 .../main/res/values/contact_diary_strings.xml | 29 ++++---
 .../src/main/res/values/styles.xml            | 26 ++++++
 63 files changed, 1625 insertions(+), 127 deletions(-)
 delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryRootModule.kt
 delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
 delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt
 delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryUIModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayNavigationEvents.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogViewModel.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogViewModel.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayFragmentsAdapter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayTab.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListAdapter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListViewModel.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListAdapter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListViewModel.kt
 delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModul.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/ContactDiaryExtensions.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/MarginRecyclerViewDecoration.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/SelectableItem.kt
 create mode 100644 Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_locations.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_people.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_illustration_no_locations.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_illustration_no_people.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_selected.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_unselected.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_location_bottom_sheet_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_location_list_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_location_list_line.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_person_bottom_sheet_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_person_list_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_person_list_line.xml

diff --git a/Corona-Warn-App/src/main/AndroidManifest.xml b/Corona-Warn-App/src/main/AndroidManifest.xml
index 1d0b39de8..e450de6d4 100644
--- a/Corona-Warn-App/src/main/AndroidManifest.xml
+++ b/Corona-Warn-App/src/main/AndroidManifest.xml
@@ -80,7 +80,7 @@
             android:name=".contactdiary.ui.ContactDiaryActivity"
             android:exported="false"
             android:screenOrientation="portrait"
-            android:theme="@style/AppTheme.NoActionBar" />
+            android:theme="@style/AppTheme.ContactDiary" />
 
     </application>
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt
deleted file mode 100644
index e2529d15f..000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.rki.coronawarnapp.contactdiary
-
-import dagger.Module
-import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryStorageModule
-
-@Module(
-    includes = [ContactDiaryStorageModule::class]
-)
-class ContactDiaryModule
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryRootModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryRootModule.kt
new file mode 100644
index 000000000..4db7d6fde
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryRootModule.kt
@@ -0,0 +1,17 @@
+package de.rki.coronawarnapp.contactdiary
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryStorageModule
+import de.rki.coronawarnapp.contactdiary.ui.ContactDiaryActivity
+import de.rki.coronawarnapp.contactdiary.ui.ContactDiaryUIModule
+
+@Module(
+    includes = [
+        ContactDiaryStorageModule::class
+    ]
+)
+abstract class ContactDiaryRootModule {
+    @ContributesAndroidInjector(modules = [ContactDiaryUIModule::class])
+    abstract fun contactDiaryActivity(): ContactDiaryActivity
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
index 4618a0b9d..c5315a986 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt
@@ -1,6 +1,8 @@
 package de.rki.coronawarnapp.contactdiary.model
 
-interface ContactDiaryLocation {
+import de.rki.coronawarnapp.util.lists.HasStableId
+
+interface ContactDiaryLocation : HasStableId {
     val locationId: Long
     var locationName: String
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt
index 5657484a0..95badab55 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt
@@ -1,6 +1,8 @@
 package de.rki.coronawarnapp.contactdiary.model
 
-interface ContactDiaryPerson {
+import de.rki.coronawarnapp.util.lists.HasStableId
+
+interface ContactDiaryPerson : HasStableId {
     val personId: Long
     var fullName: String
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
deleted file mode 100644
index 65bf6c6e5..000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package de.rki.coronawarnapp.contactdiary.model
-
-data class DefaultContactDiaryLocation(
-    override val locationId: Long = 0L,
-    override var locationName: String
-) : ContactDiaryLocation
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt
deleted file mode 100644
index fdf73bd6e..000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package de.rki.coronawarnapp.contactdiary.model
-
-data class DefaultContactDiaryPerson(
-    override val personId: Long = 0L,
-    override var fullName: String
-) : ContactDiaryPerson
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
index ffd350e41..c424bfdee 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt
@@ -9,7 +9,10 @@ import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
 data class ContactDiaryLocationEntity(
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "locationId") override val locationId: Long = 0L,
     @ColumnInfo(name = "locationName") override var locationName: String
-) : ContactDiaryLocation
+) : ContactDiaryLocation {
+    override val stableId: Long
+        get() = locationId
+}
 
 fun ContactDiaryLocation.toContactDiaryLocationEntity(): ContactDiaryLocationEntity =
     ContactDiaryLocationEntity(this.locationId, this.locationName)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt
index be31909b9..0ea761f2c 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt
@@ -9,7 +9,10 @@ import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson
 data class ContactDiaryPersonEntity(
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "personId") override val personId: Long = 0L,
     @ColumnInfo(name = "fullName") override var fullName: String
-) : ContactDiaryPerson
+) : ContactDiaryPerson {
+    override val stableId: Long
+        get() = personId
+}
 
 fun ContactDiaryPerson.toContactDiaryPersonEntity(): ContactDiaryPersonEntity =
     ContactDiaryPersonEntity(this.personId, this.fullName)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt
index 91a482917..6e2edbb9f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt
@@ -85,10 +85,8 @@ class DefaultContactDiaryRepository @Inject constructor(
 
     override suspend fun addLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) {
         Timber.d("Adding location visit $contactDiaryLocationVisit")
-        executeWhenIdNotDefault(contactDiaryLocationVisit.id) {
-            val contactDiaryLocationVisitEntity = contactDiaryLocationVisit.toContactDiaryLocationVisitEntity()
-            contactDiaryLocationVisitDao.insert(contactDiaryLocationVisitEntity)
-        }
+        val contactDiaryLocationVisitEntity = contactDiaryLocationVisit.toContactDiaryLocationVisitEntity()
+        contactDiaryLocationVisitDao.insert(contactDiaryLocationVisitEntity)
     }
 
     override suspend fun deleteLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryModule.kt
deleted file mode 100644
index 8aca513cd..000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryModule.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.rki.coronawarnapp.contactdiary.ui
-
-import dagger.Module
-import dagger.android.ContributesAndroidInjector
-import de.rki.coronawarnapp.contactdiary.ui.onboarding.ContactDiaryOnboardingFragment
-import de.rki.coronawarnapp.contactdiary.ui.onboarding.ContactDiaryOnboardingFragmentModule
-import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragment
-import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragmentModule
-
-@Module
-abstract class ContactDiaryModule {
-    @ContributesAndroidInjector(modules = [ContactDiaryOnboardingFragmentModule::class])
-    abstract fun contactDiaryOnboardingFragment(): ContactDiaryOnboardingFragment
-
-    @ContributesAndroidInjector(modules = [ContactDiaryOverviewFragmentModule::class])
-    abstract fun contactDiaryOverviewFragment(): ContactDiaryOverviewFragment
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryUIModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryUIModule.kt
new file mode 100644
index 000000000..0ddeb1ca0
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/ContactDiaryUIModule.kt
@@ -0,0 +1,42 @@
+package de.rki.coronawarnapp.contactdiary.ui
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import de.rki.coronawarnapp.contactdiary.ui.day.ContactDiaryDayFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.ContactDiaryDayModule
+import de.rki.coronawarnapp.contactdiary.ui.day.sheets.location.ContactDiaryLocationBottomSheetDialogFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.sheets.location.ContactDiaryLocationBottomSheetDialogModule
+import de.rki.coronawarnapp.contactdiary.ui.day.sheets.person.ContactDiaryPersonBottomSheetDialogFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.sheets.person.ContactDiaryPersonBottomSheetDialogModule
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.ContactDiaryLocationListFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.ContactDiaryLocationListModule
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.ContactDiaryPersonListFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.ContactDiaryPersonListModule
+import de.rki.coronawarnapp.contactdiary.ui.onboarding.ContactDiaryOnboardingFragment
+import de.rki.coronawarnapp.contactdiary.ui.onboarding.ContactDiaryOnboardingFragmentModule
+import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragment
+import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragmentModule
+
+@Module
+abstract class ContactDiaryUIModule {
+    @ContributesAndroidInjector(modules = [ContactDiaryDayModule::class])
+    abstract fun contactDiaryDayFragment(): ContactDiaryDayFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryPersonListModule::class])
+    abstract fun contactDiaryPersonListFragment(): ContactDiaryPersonListFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryLocationListModule::class])
+    abstract fun contactDiaryLocationListFragment(): ContactDiaryLocationListFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryPersonBottomSheetDialogModule::class])
+    abstract fun contactDiaryPersonBottomSheetDialogFragment(): ContactDiaryPersonBottomSheetDialogFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryLocationBottomSheetDialogModule::class])
+    abstract fun contactDiaryLocationBottomSheetDialogFragment(): ContactDiaryLocationBottomSheetDialogFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryOnboardingFragmentModule::class])
+    abstract fun contactDiaryOnboardingFragment(): ContactDiaryOnboardingFragment
+
+    @ContributesAndroidInjector(modules = [ContactDiaryOverviewFragmentModule::class])
+    abstract fun contactDiaryOverviewFragment(): ContactDiaryOverviewFragment
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayFragment.kt
new file mode 100644
index 000000000..b43c3bfb1
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayFragment.kt
@@ -0,0 +1,82 @@
+package de.rki.coronawarnapp.contactdiary.ui.day
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
+import com.google.android.material.tabs.TabLayoutMediator
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.ContactDiaryDayFragmentsAdapter
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.ContactDiaryDayTab
+import de.rki.coronawarnapp.contactdiary.util.registerOnPageChangeCallback
+import de.rki.coronawarnapp.databinding.ContactDiaryDayFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.doNavigate
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.ui.popBackStack
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
+import javax.inject.Inject
+
+class ContactDiaryDayFragment : Fragment(R.layout.contact_diary_day_fragment), AutoInject {
+    private val binding: ContactDiaryDayFragmentBinding by viewBindingLazy()
+
+    private val navArgs by navArgs<ContactDiaryDayFragmentArgs>()
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: ContactDiaryDayViewModel by cwaViewModelsAssisted(
+        factoryProducer = { viewModelFactory },
+        constructorCall = { factory, _ ->
+            factory as ContactDiaryDayViewModel.Factory
+            factory.create(navArgs.selectedDay)
+        }
+    )
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val contactDiaryTabs = listOf(ContactDiaryDayTab.PersonTab, ContactDiaryDayTab.LocationTab)
+
+        val adapter = ContactDiaryDayFragmentsAdapter(this, contactDiaryTabs, navArgs.selectedDay)
+
+        binding.contactDiaryDayViewPager.adapter = adapter
+
+        TabLayoutMediator(binding.contactDiaryDayTabLayout, binding.contactDiaryDayViewPager) { tab, position ->
+            val tabSource = adapter.tabs[position]
+            tab.setText(tabSource.tabNameResource)
+        }.attach()
+
+        binding.apply {
+            contactDiaryDayViewPager.registerOnPageChangeCallback {
+                binding.contactDiaryDayFab.setText(adapter.tabs[it].fabTextResource)
+            }
+
+            contactDiaryDayFab.setOnClickListener {
+                viewModel.onCreateButtonClicked(adapter.tabs[contactDiaryDayTabLayout.selectedTabPosition])
+            }
+
+            contactDiaryDayHeader.headerButtonBack.buttonIcon.setOnClickListener {
+                viewModel.onBackPressed()
+            }
+        }
+
+        viewModel.uiState.observe2(this) {
+            binding.contactDiaryDayHeader.title = it.dayText
+        }
+
+        viewModel.routeToScreen.observe2(this) {
+            when (it) {
+                ContactDiaryDayNavigationEvents.NavigateToOverviewFragment -> popBackStack()
+                ContactDiaryDayNavigationEvents.NavigateToAddPersonBottomSheet -> doNavigate(
+                    ContactDiaryDayFragmentDirections
+                        .actionContactDiaryDayFragmentToContactDiaryPersonBottomSheetDialogFragment()
+                )
+                ContactDiaryDayNavigationEvents.NavigateToAddLocationBottomSheet -> doNavigate(
+                    ContactDiaryDayFragmentDirections
+                        .actionContactDiaryDayFragmentToContactDiaryLocationBottomSheetDialogFragment()
+                )
+            }
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayModule.kt
new file mode 100644
index 000000000..a0fe530c9
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.contactdiary.ui.day
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class ContactDiaryDayModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(ContactDiaryDayViewModel::class)
+    abstract fun contactDiaryDayFragment(
+        factory: ContactDiaryDayViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayNavigationEvents.kt
new file mode 100644
index 000000000..8524c3144
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayNavigationEvents.kt
@@ -0,0 +1,7 @@
+package de.rki.coronawarnapp.contactdiary.ui.day
+
+sealed class ContactDiaryDayNavigationEvents {
+    object NavigateToOverviewFragment : ContactDiaryDayNavigationEvents()
+    object NavigateToAddPersonBottomSheet : ContactDiaryDayNavigationEvents()
+    object NavigateToAddLocationBottomSheet : ContactDiaryDayNavigationEvents()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt
new file mode 100644
index 000000000..dfe45bf08
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt
@@ -0,0 +1,53 @@
+package de.rki.coronawarnapp.contactdiary.ui.day
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.Assisted
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.ContactDiaryDayTab
+import de.rki.coronawarnapp.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.map
+import org.joda.time.LocalDate
+import org.joda.time.format.DateTimeFormat
+
+class ContactDiaryDayViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    @Assisted selectedDay: String
+) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
+    private val dateFormat by lazy {
+        DateTimeFormat.forPattern("EEEE, dd.MM.yy")
+    }
+
+    private val displayedDay = MutableStateFlow(LocalDate.parse(selectedDay))
+
+    val routeToScreen: SingleLiveEvent<ContactDiaryDayNavigationEvents> = SingleLiveEvent()
+
+    val uiState = displayedDay.map { day ->
+        UIState(dayText = day.toString(dateFormat))
+    }.asLiveData()
+
+    fun onCreateButtonClicked(activeTab: ContactDiaryDayTab) {
+        when (activeTab) {
+            ContactDiaryDayTab.LocationTab -> routeToScreen
+                .postValue(ContactDiaryDayNavigationEvents.NavigateToAddLocationBottomSheet)
+            ContactDiaryDayTab.PersonTab -> routeToScreen
+                .postValue(ContactDiaryDayNavigationEvents.NavigateToAddPersonBottomSheet)
+        }
+    }
+
+    fun onBackPressed() {
+        routeToScreen.postValue(ContactDiaryDayNavigationEvents.NavigateToOverviewFragment)
+    }
+
+    data class UIState(
+        val dayText: String
+    )
+
+    @AssistedInject.Factory
+    interface Factory : CWAViewModelFactory<ContactDiaryDayViewModel> {
+        fun create(selectedDay: String): ContactDiaryDayViewModel
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogFragment.kt
new file mode 100644
index 000000000..f480e75dd
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogFragment.kt
@@ -0,0 +1,57 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.location
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.widget.doAfterTextChanged
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import de.rki.coronawarnapp.databinding.ContactDiaryLocationBottomSheetFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
+
+class ContactDiaryLocationBottomSheetDialogFragment : BottomSheetDialogFragment(), AutoInject {
+    private var _binding: ContactDiaryLocationBottomSheetFragmentBinding? = null
+    private val binding get() = _binding!!
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: ContactDiaryLocationBottomSheetDialogViewModel by cwaViewModels { viewModelFactory }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+        _binding = ContactDiaryLocationBottomSheetFragmentBinding.inflate(inflater)
+        return binding.root
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        binding.contactDiaryLocationBottomSheetCloseButton.buttonIcon.setOnClickListener {
+            viewModel.closePressed()
+        }
+
+        binding.contactDiaryLocationBottomSheetSaveButton.setOnClickListener {
+            viewModel.saveLocation()
+        }
+
+        binding.contactDiaryLocationBottomSheetTextInputEditText.doAfterTextChanged {
+            viewModel.textChanged(it.toString())
+        }
+
+        viewModel.shouldClose.observe2(this) {
+            dismiss()
+        }
+
+        viewModel.isValid.observe2(this) {
+            binding.contactDiaryLocationBottomSheetTextInputLayout.isErrorEnabled = it
+            binding.contactDiaryLocationBottomSheetSaveButton.isEnabled = it
+        }
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogModule.kt
new file mode 100644
index 000000000..4acd5dd2f
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.location
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class ContactDiaryLocationBottomSheetDialogModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(ContactDiaryLocationBottomSheetDialogViewModel::class)
+    abstract fun contactDiaryLocationBottomSheetDialogFragment(
+        factory: ContactDiaryLocationBottomSheetDialogViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogViewModel.kt
new file mode 100644
index 000000000..974945328
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/location/ContactDiaryLocationBottomSheetDialogViewModel.kt
@@ -0,0 +1,49 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.location
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationEntity
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.map
+
+class ContactDiaryLocationBottomSheetDialogViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    private val contactDiaryRepository: ContactDiaryRepository
+) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
+    private val text = MutableStateFlow("")
+
+    val isValid = text.map {
+        it.isNotEmpty() && it.length <= MAX_LOCATION_NAME_LENGTH
+    }.asLiveData()
+
+    val shouldClose = SingleLiveEvent<Unit>()
+
+    fun textChanged(locationName: String) {
+        text.value = locationName
+    }
+
+    fun saveLocation() = launch {
+        contactDiaryRepository.addLocation(
+            ContactDiaryLocationEntity(
+                locationName = text.value.take(MAX_LOCATION_NAME_LENGTH)
+            )
+        )
+        shouldClose.postValue(null)
+    }
+
+    fun closePressed() {
+        shouldClose.postValue(null)
+    }
+
+    companion object {
+        private const val MAX_LOCATION_NAME_LENGTH = 250
+    }
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<ContactDiaryLocationBottomSheetDialogViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogFragment.kt
new file mode 100644
index 000000000..a96fdb12f
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogFragment.kt
@@ -0,0 +1,57 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.person
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.widget.doAfterTextChanged
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import de.rki.coronawarnapp.databinding.ContactDiaryPersonBottomSheetFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
+
+class ContactDiaryPersonBottomSheetDialogFragment : BottomSheetDialogFragment(), AutoInject {
+    private var _binding: ContactDiaryPersonBottomSheetFragmentBinding? = null
+    private val binding get() = _binding!!
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: ContactDiaryPersonBottomSheetDialogViewModel by cwaViewModels { viewModelFactory }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+        _binding = ContactDiaryPersonBottomSheetFragmentBinding.inflate(inflater)
+        return binding.root
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        binding.contactDiaryPersonBottomSheetCloseButton.buttonIcon.setOnClickListener {
+            viewModel.closePressed()
+        }
+
+        binding.contactDiaryPersonBottomSheetSaveButton.setOnClickListener {
+            viewModel.savePerson()
+        }
+
+        binding.contactDiaryPersonBottomSheetTextInputEditText.doAfterTextChanged {
+            viewModel.textChanged(it.toString())
+        }
+
+        viewModel.shouldClose.observe2(this) {
+            dismiss()
+        }
+
+        viewModel.isValid.observe2(this) {
+            binding.contactDiaryPersonBottomSheetTextInputLayout.isErrorEnabled = it
+            binding.contactDiaryPersonBottomSheetSaveButton.isEnabled = it
+        }
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogModule.kt
new file mode 100644
index 000000000..4b710bec8
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.person
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class ContactDiaryPersonBottomSheetDialogModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(ContactDiaryPersonBottomSheetDialogViewModel::class)
+    abstract fun contactDiaryPersonBottomSheetDialogFragment(
+        factory: ContactDiaryPersonBottomSheetDialogViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogViewModel.kt
new file mode 100644
index 000000000..39f00ca23
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/sheets/person/ContactDiaryPersonBottomSheetDialogViewModel.kt
@@ -0,0 +1,49 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.sheets.person
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEntity
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.map
+
+class ContactDiaryPersonBottomSheetDialogViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    private val contactDiaryRepository: ContactDiaryRepository
+) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
+    private val text = MutableStateFlow("")
+
+    val isValid = text.map {
+        it.isNotEmpty() && it.length <= MAX_PERSON_NAME_LENGTH
+    }.asLiveData()
+
+    val shouldClose = SingleLiveEvent<Unit>()
+
+    fun textChanged(locationName: String) {
+        text.value = locationName
+    }
+
+    fun savePerson() = launch {
+        contactDiaryRepository.addPerson(
+            ContactDiaryPersonEntity(
+                fullName = text.value.take(MAX_PERSON_NAME_LENGTH)
+            )
+        )
+        shouldClose.postValue(null)
+    }
+
+    fun closePressed() {
+        shouldClose.postValue(null)
+    }
+
+    companion object {
+        private const val MAX_PERSON_NAME_LENGTH = 250
+    }
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<ContactDiaryPersonBottomSheetDialogViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayFragmentsAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayFragmentsAdapter.kt
new file mode 100644
index 000000000..cbb7a2b77
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayFragmentsAdapter.kt
@@ -0,0 +1,14 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class ContactDiaryDayFragmentsAdapter(
+    fragment: Fragment,
+    val tabs: List<ContactDiaryDayTab>,
+    private val day: String
+) : FragmentStateAdapter(fragment) {
+    override fun getItemCount() = tabs.size
+
+    override fun createFragment(position: Int): Fragment = tabs[position].fragmentInstantiation(day)
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayTab.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayTab.kt
new file mode 100644
index 000000000..59c65922a
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/ContactDiaryDayTab.kt
@@ -0,0 +1,36 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs
+
+import androidx.fragment.app.Fragment
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.ContactDiaryLocationListFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.ContactDiaryLocationListFragmentArgs
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.ContactDiaryPersonListFragment
+import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.ContactDiaryPersonListFragmentArgs
+
+sealed class ContactDiaryDayTab(
+    val tabNameResource: Int,
+    val fabTextResource: Int,
+    val fragmentInstantiation: (day: String) -> Fragment
+) {
+    object PersonTab : ContactDiaryDayTab(
+        R.string.contact_diary_day_person_tab_title,
+        R.string.contact_diary_day_person_fab_title,
+        { day ->
+            ContactDiaryPersonListFragment().apply {
+                // Feels kind of hacky but i like the free typesafety for the args
+                arguments = ContactDiaryPersonListFragmentArgs(day).toBundle()
+            }
+        }
+    )
+
+    object LocationTab : ContactDiaryDayTab(
+        R.string.contact_diary_day_location_tab_title,
+        R.string.contact_diary_day_location_fab_title,
+        { day ->
+            ContactDiaryLocationListFragment().apply {
+                // Feels kind of hacky but i like the free typesafety for the args
+                arguments = ContactDiaryLocationListFragmentArgs(day).toBundle()
+            }
+        }
+    )
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListAdapter.kt
new file mode 100644
index 000000000..70490cc8c
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListAdapter.kt
@@ -0,0 +1,52 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.location
+
+import android.view.ViewGroup
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.util.SelectableItem
+import de.rki.coronawarnapp.databinding.ContactDiaryLocationListLineBinding
+import de.rki.coronawarnapp.ui.lists.BaseAdapter
+import de.rki.coronawarnapp.util.lists.BindableVH
+import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffUtilAdapter
+import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffer
+
+class ContactDiaryLocationListAdapter(
+    private val onTappedCallback: (item: SelectableItem<ContactDiaryLocation>) -> Unit
+) : BaseAdapter<ContactDiaryLocationListAdapter.CachedLocationViewHolder>(),
+    AsyncDiffUtilAdapter<SelectableItem<ContactDiaryLocation>> {
+
+    override val asyncDiffer: AsyncDiffer<SelectableItem<ContactDiaryLocation>> = AsyncDiffer(this)
+
+    override fun getItemCount(): Int = data.size
+
+    override fun getItemId(position: Int): Long = data[position].stableId
+
+    override fun onCreateBaseVH(parent: ViewGroup, viewType: Int): CachedLocationViewHolder =
+        CachedLocationViewHolder(parent)
+
+    override fun onBindBaseVH(holder: CachedLocationViewHolder, position: Int) {
+        val item = data[position]
+        holder.itemView.setOnClickListener {
+            onTappedCallback(item)
+        }
+        holder.bind(item)
+    }
+
+    class CachedLocationViewHolder(
+        parent: ViewGroup
+    ) : BaseAdapter.VH(R.layout.contact_diary_location_list_line, parent),
+        BindableVH<SelectableItem<ContactDiaryLocation>, ContactDiaryLocationListLineBinding> {
+        override val viewBinding = lazy { ContactDiaryLocationListLineBinding.bind(itemView) }
+
+        override val onBindData: ContactDiaryLocationListLineBinding.(
+            key: SelectableItem<ContactDiaryLocation>
+        ) -> Unit =
+            {
+                contactDiaryLocationListLineName.text = it.item.locationName
+                when (it.selected) {
+                    true -> contactDiaryLocationListLineIcon.setImageResource(R.drawable.ic_selected)
+                    false -> contactDiaryLocationListLineIcon.setImageResource(R.drawable.ic_unselected)
+                }
+            }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListFragment.kt
new file mode 100644
index 000000000..4d7582902
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListFragment.kt
@@ -0,0 +1,55 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.location
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.util.MarginRecyclerViewDecoration
+import de.rki.coronawarnapp.databinding.ContactDiaryLocationListFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.lists.diffutil.update
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.ui.setInvisible
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
+import javax.inject.Inject
+
+class ContactDiaryLocationListFragment : Fragment(R.layout.contact_diary_location_list_fragment), AutoInject {
+    private val binding: ContactDiaryLocationListFragmentBinding by viewBindingLazy()
+
+    private val navArgs by navArgs<ContactDiaryLocationListFragmentArgs>()
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: ContactDiaryLocationListViewModel by cwaViewModelsAssisted(
+        factoryProducer = { viewModelFactory },
+        constructorCall = { factory, _ ->
+            factory as ContactDiaryLocationListViewModel.Factory
+            factory.create(navArgs.selectedDay)
+        }
+    )
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val locationListAdapter = ContactDiaryLocationListAdapter {
+            viewModel.locationSelectionChanged(it)
+        }
+
+        binding.contactDiaryLocationListRecyclerView.apply {
+            adapter = locationListAdapter
+            addItemDecoration(
+                MarginRecyclerViewDecoration(
+                    resources.getDimensionPixelSize(R.dimen.spacing_tiny)
+                )
+            )
+        }
+
+        viewModel.uiList.observe2(this) {
+            locationListAdapter.update(it)
+
+            binding.contactDiaryLocationListNoItemsGroup.setInvisible(it.isNotEmpty())
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListModule.kt
new file mode 100644
index 000000000..199dfbcb7
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.location
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class ContactDiaryLocationListModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(ContactDiaryLocationListViewModel::class)
+    abstract fun contactDiaryLocationListFragment(
+        factory: ContactDiaryLocationListViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListViewModel.kt
new file mode 100644
index 000000000..e0b822eab
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/location/ContactDiaryLocationListViewModel.kt
@@ -0,0 +1,57 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.location
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.Assisted
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocationVisit
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.contactdiary.util.SelectableItem
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
+import org.joda.time.LocalDate
+
+class ContactDiaryLocationListViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    @Assisted selectedDay: String,
+    private val contactDiaryRepository: ContactDiaryRepository
+) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
+
+    private val localDate = LocalDate.parse(selectedDay)
+
+    private val dayElement = contactDiaryRepository.locationVisitsForDate(localDate)
+    private val selectableLocations = contactDiaryRepository.locations
+
+    val uiList = selectableLocations.combine(dayElement) { locations, dayElement ->
+        locations.map { contactDiaryLocation ->
+            if (dayElement.any { it.contactDiaryLocation.locationId == contactDiaryLocation.locationId }) {
+                SelectableItem(true, contactDiaryLocation)
+            } else {
+                SelectableItem(false, contactDiaryLocation)
+            }
+        }
+    }.asLiveData()
+
+    fun locationSelectionChanged(item: SelectableItem<ContactDiaryLocation>) = launch {
+        if (!item.selected) {
+            contactDiaryRepository.addLocationVisit(
+                DefaultContactDiaryLocationVisit(
+                    date = localDate,
+                    contactDiaryLocation = item.item
+                )
+            )
+        } else {
+            val visit = dayElement.first()
+                .find { it.contactDiaryLocation.locationId == item.item.locationId }
+            visit?.let { contactDiaryRepository.deleteLocationVisit(it) }
+        }
+    }
+
+    @AssistedInject.Factory
+    interface Factory : CWAViewModelFactory<ContactDiaryLocationListViewModel> {
+        fun create(selectedDay: String): ContactDiaryLocationListViewModel
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListAdapter.kt
new file mode 100644
index 000000000..7829a7492
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListAdapter.kt
@@ -0,0 +1,51 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.person
+
+import android.view.ViewGroup
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson
+import de.rki.coronawarnapp.contactdiary.util.SelectableItem
+import de.rki.coronawarnapp.databinding.ContactDiaryPersonListLineBinding
+import de.rki.coronawarnapp.ui.lists.BaseAdapter
+import de.rki.coronawarnapp.util.lists.BindableVH
+import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffUtilAdapter
+import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffer
+
+class ContactDiaryPersonListAdapter(
+    private val onTappedCallback: (item: SelectableItem<ContactDiaryPerson>) -> Unit
+) : BaseAdapter<ContactDiaryPersonListAdapter.CachedPersonViewHolder>(),
+    AsyncDiffUtilAdapter<SelectableItem<ContactDiaryPerson>> {
+
+    override val asyncDiffer: AsyncDiffer<SelectableItem<ContactDiaryPerson>> = AsyncDiffer(this)
+
+    override fun getItemCount(): Int = data.size
+
+    override fun getItemId(position: Int): Long = data[position].stableId
+
+    override fun onCreateBaseVH(parent: ViewGroup, viewType: Int): CachedPersonViewHolder =
+        CachedPersonViewHolder(parent)
+
+    override fun onBindBaseVH(holder: CachedPersonViewHolder, position: Int) {
+        val item = data[position]
+        holder.itemView.setOnClickListener {
+            onTappedCallback(item)
+        }
+        holder.bind(item)
+    }
+
+    class CachedPersonViewHolder(
+        parent: ViewGroup
+    ) : BaseAdapter.VH(R.layout.contact_diary_person_list_line, parent),
+        BindableVH<SelectableItem<ContactDiaryPerson>, ContactDiaryPersonListLineBinding> {
+        override val viewBinding = lazy { ContactDiaryPersonListLineBinding.bind(itemView) }
+
+        override val onBindData: ContactDiaryPersonListLineBinding.(
+            key: SelectableItem<ContactDiaryPerson>
+        ) -> Unit = {
+            contactDiaryPersonListLineName.text = it.item.fullName
+            when (it.selected) {
+                true -> contactDiaryPersonListLineIcon.setImageResource(R.drawable.ic_selected)
+                false -> contactDiaryPersonListLineIcon.setImageResource(R.drawable.ic_unselected)
+            }
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListFragment.kt
new file mode 100644
index 000000000..d5ed5aef5
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListFragment.kt
@@ -0,0 +1,55 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.person
+
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.navArgs
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.util.MarginRecyclerViewDecoration
+import de.rki.coronawarnapp.databinding.ContactDiaryPersonListFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.lists.diffutil.update
+import de.rki.coronawarnapp.util.ui.observe2
+import de.rki.coronawarnapp.util.ui.setInvisible
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
+import javax.inject.Inject
+
+class ContactDiaryPersonListFragment : Fragment(R.layout.contact_diary_person_list_fragment), AutoInject {
+    private val binding: ContactDiaryPersonListFragmentBinding by viewBindingLazy()
+
+    private val navArgs by navArgs<ContactDiaryPersonListFragmentArgs>()
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    private val viewModel: ContactDiaryPersonListViewModel by cwaViewModelsAssisted(
+        factoryProducer = { viewModelFactory },
+        constructorCall = { factory, _ ->
+            factory as ContactDiaryPersonListViewModel.Factory
+            factory.create(navArgs.selectedDay)
+        }
+    )
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val personListAdapter = ContactDiaryPersonListAdapter {
+            viewModel.personSelectionChanged(it)
+        }
+
+        binding.contactDiaryPersonListRecyclerView.apply {
+            adapter = personListAdapter
+            addItemDecoration(
+                MarginRecyclerViewDecoration(
+                    resources.getDimensionPixelSize(R.dimen.spacing_tiny)
+                )
+            )
+        }
+
+        viewModel.uiList.observe2(this) {
+            personListAdapter.update(it)
+
+            binding.contactDiaryPersonListNoItemsGroup.setInvisible(it.isNotEmpty())
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListModule.kt
new file mode 100644
index 000000000..22c393ce2
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.person
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class ContactDiaryPersonListModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(ContactDiaryPersonListViewModel::class)
+    abstract fun contactDiaryPersonListFragment(
+        factory: ContactDiaryPersonListViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListViewModel.kt
new file mode 100644
index 000000000..29b48d3b6
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/tabs/person/ContactDiaryPersonListViewModel.kt
@@ -0,0 +1,57 @@
+package de.rki.coronawarnapp.contactdiary.ui.day.tabs.person
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.Assisted
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson
+import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounter
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.contactdiary.util.SelectableItem
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
+import org.joda.time.LocalDate
+
+class ContactDiaryPersonListViewModel @AssistedInject constructor(
+    dispatcherProvider: DispatcherProvider,
+    @Assisted selectedDay: String,
+    private val contactDiaryRepository: ContactDiaryRepository
+) : CWAViewModel(dispatcherProvider = dispatcherProvider) {
+
+    private val localDate = LocalDate.parse(selectedDay)
+
+    private val dayElement = contactDiaryRepository.personEncountersForDate(localDate)
+    private val selectablePersons = contactDiaryRepository.people
+
+    val uiList = selectablePersons.combine(dayElement) { persons, dayElement ->
+        persons.map { contactDiaryPerson ->
+            if (dayElement.any { it.contactDiaryPerson.personId == contactDiaryPerson.personId }) {
+                SelectableItem(true, contactDiaryPerson)
+            } else {
+                SelectableItem(false, contactDiaryPerson)
+            }
+        }
+    }.asLiveData()
+
+    fun personSelectionChanged(item: SelectableItem<ContactDiaryPerson>) = launch {
+        if (!item.selected) {
+            contactDiaryRepository.addPersonEncounter(
+                DefaultContactDiaryPersonEncounter(
+                    date = localDate,
+                    contactDiaryPerson = item.item
+                )
+            )
+        } else {
+            val visit = dayElement.first()
+                .find { it.contactDiaryPerson.personId == item.item.personId }
+            visit?.let { contactDiaryRepository.deletePersonEncounter(it) }
+        }
+    }
+
+    @AssistedInject.Factory
+    interface Factory : CWAViewModelFactory<ContactDiaryPersonListViewModel> {
+        fun create(selectedDay: String): ContactDiaryPersonListViewModel
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragment.kt
index c037f5c4e..d4bdaafbc 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragment.kt
@@ -3,7 +3,6 @@ package de.rki.coronawarnapp.contactdiary.ui.onboarding
 import android.os.Bundle
 import android.view.View
 import androidx.fragment.app.Fragment
-import androidx.navigation.ActionOnlyNavDirections
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.contactdiary.ui.ContactDiaryActivity
 import de.rki.coronawarnapp.databinding.ContactDiaryOnboardingFragmentBinding
@@ -46,24 +45,18 @@ class ContactDiaryOnboardingFragment : Fragment(R.layout.contact_diary_onboardin
 
                 ContactDiaryOnboardingNavigationEvents.NavigateToPrivacyFragment -> {
                     doNavigate(
-                        ActionOnlyNavDirections(
-                            R.id.action_contactDiaryOnboardingFragment_to_contactDiaryInformationPrivacyFragment
-                        )
+                        ContactDiaryOnboardingFragmentDirections
+                            .actionContactDiaryOnboardingFragmentToContactDiaryInformationPrivacyFragment()
                     )
                 }
 
                 ContactDiaryOnboardingNavigationEvents.NavigateToOverviewFragment -> {
                     doNavigate(
-                        ActionOnlyNavDirections(
-                            R.id.action_contactDiaryOnboardingFragment_to_contactDiaryOverviewFragment
-                        )
+                        ContactDiaryOnboardingFragmentDirections
+                            .actionContactDiaryOnboardingFragmentToContactDiaryOverviewFragment()
                     )
                 }
             }
         }
     }
-
-    override fun onResume() {
-        super.onResume()
-    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModul.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModul.kt
deleted file mode 100644
index 0b338fb70..000000000
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModul.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.rki.coronawarnapp.contactdiary.ui.onboarding
-
-import dagger.Binds
-import dagger.Module
-import dagger.android.ContributesAndroidInjector
-import dagger.multibindings.IntoMap
-import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
-import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
-import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
-
-@Module
-abstract class ContactDiaryOnboardingFragmentModul {
-
-    @Binds
-    @IntoMap
-    @CWAViewModelKey(ContactDiaryOnboardingFragmentViewModel::class)
-    abstract fun contactDiaryOnboardingFragmentVM(
-        factory: ContactDiaryOnboardingFragmentViewModel.Factory
-    ): CWAViewModelFactory<out CWAViewModel>
-
-    @ContributesAndroidInjector
-    abstract fun contactDiaryOnboardingFragmentVM(): ContactDiaryOnboardingFragment
-}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModule.kt
index 55afd7903..9f96cf4c5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModule.kt
@@ -9,7 +9,6 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
 
 @Module
 abstract class ContactDiaryOnboardingFragmentModule {
-
     @Binds
     @IntoMap
     @CWAViewModelKey(ContactDiaryOnboardingFragmentViewModel::class)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingNavigationEvents.kt
index 62578f22e..2ead88460 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingNavigationEvents.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingNavigationEvents.kt
@@ -1,7 +1,6 @@
 package de.rki.coronawarnapp.contactdiary.ui.onboarding
 
 sealed class ContactDiaryOnboardingNavigationEvents {
-
     object NavigateToMainActivity : ContactDiaryOnboardingNavigationEvents()
     object NavigateToPrivacyFragment : ContactDiaryOnboardingNavigationEvents()
     object NavigateToOverviewFragment : ContactDiaryOnboardingNavigationEvents()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt
index 6711d86dd..63a39c72f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt
@@ -2,12 +2,12 @@ package de.rki.coronawarnapp.contactdiary.ui.overview
 
 import android.os.Bundle
 import android.view.View
-import android.widget.Toast
 import androidx.fragment.app.Fragment
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ContactDiaryOverviewAdapter
 import de.rki.coronawarnapp.databinding.ContactDiaryOverviewFragmentBinding
 import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.observe2
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
@@ -48,12 +48,10 @@ class ContactDiaryOverviewFragment : Fragment(R.layout.contact_diary_overview_fr
                 }
 
                 is ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment -> {
-                    // TODO(Really navigate to ContactDiaryDayFragment once it is merged)
-                    Toast.makeText(
-                        requireContext(),
-                        "Navigate to ContactDiaryDayFragment with date ${it.localDateString}",
-                        Toast.LENGTH_SHORT
-                    ).show()
+                    doNavigate(
+                        ContactDiaryOverviewFragmentDirections
+                            .actionContactDiaryOverviewFragmentToContactDiaryDayFragment(it.localDateString)
+                    )
                 }
             }
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt
index 23c65456c..ca3dba936 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt
@@ -2,7 +2,6 @@ package de.rki.coronawarnapp.contactdiary.ui.overview
 
 import dagger.Binds
 import dagger.Module
-import dagger.android.ContributesAndroidInjector
 import dagger.multibindings.IntoMap
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
@@ -10,14 +9,10 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
 
 @Module
 abstract class ContactDiaryOverviewFragmentModule {
-
     @Binds
     @IntoMap
     @CWAViewModelKey(ContactDiaryOverviewViewModel::class)
     abstract fun contactDiaryOverviewFragmentVM(
         factory: ContactDiaryOverviewViewModel.Factory
     ): CWAViewModelFactory<out CWAViewModel>
-
-    @ContributesAndroidInjector
-    abstract fun contactDiaryOverviewFragmentVM(): ContactDiaryOverviewFragment
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt
index e3827f479..6f757e681 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt
@@ -3,8 +3,6 @@ package de.rki.coronawarnapp.contactdiary.ui.overview
 import android.content.Context
 import android.view.View
 import android.widget.PopupMenu
-import androidx.navigation.NavController
-import androidx.navigation.fragment.findNavController
 import de.rki.coronawarnapp.R
 import javax.inject.Inject
 
@@ -13,9 +11,6 @@ class ContactDiaryOverviewMenu @Inject constructor(
 ) {
     private val context: Context = contactDiaryOverviewFragment.requireContext()
 
-    private val navController: NavController
-        get() = contactDiaryOverviewFragment.findNavController()
-
     fun showMenuFor(view: View) = PopupMenu(context, view).apply {
         inflate(R.menu.menu_contact_diary_overview)
         setOnMenuItemClickListener {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt
index dc5c1b920..0b23724e9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt
@@ -3,7 +3,6 @@ package de.rki.coronawarnapp.contactdiary.ui.overview
 import org.joda.time.LocalDate
 
 sealed class ContactDiaryOverviewNavigationEvents {
-
     object NavigateToMainActivity : ContactDiaryOverviewNavigationEvents()
     class NavigateToContactDiaryDayFragment(localDate: LocalDate) : ContactDiaryOverviewNavigationEvents() {
         val localDateString = localDate.toString()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
index 6040579a7..2d77b68d9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
@@ -18,7 +18,6 @@ import timber.log.Timber
 class ContactDiaryOverviewViewModel @AssistedInject constructor(
     contactDiaryRepository: ContactDiaryRepository
 ) : CWAViewModel() {
-
     val routeToScreen: SingleLiveEvent<ContactDiaryOverviewNavigationEvents> = SingleLiveEvent()
 
     private val dates = flowOf((0 until DAY_COUNT).map { LocalDate.now().minusDays(it) })
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/ContactDiaryExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/ContactDiaryExtensions.kt
new file mode 100644
index 000000000..e8083d9a5
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/ContactDiaryExtensions.kt
@@ -0,0 +1,11 @@
+package de.rki.coronawarnapp.contactdiary.util
+
+import androidx.viewpager2.widget.ViewPager2
+
+fun ViewPager2.registerOnPageChangeCallback(cb: (position: Int) -> Unit) {
+    this.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
+        override fun onPageSelected(position: Int) {
+            cb(position)
+        }
+    })
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/MarginRecyclerViewDecoration.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/MarginRecyclerViewDecoration.kt
new file mode 100644
index 000000000..683215f3f
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/MarginRecyclerViewDecoration.kt
@@ -0,0 +1,23 @@
+package de.rki.coronawarnapp.contactdiary.util
+
+import android.graphics.Rect
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+
+class MarginRecyclerViewDecoration(private val size: Int) : RecyclerView.ItemDecoration() {
+    override fun getItemOffsets(
+        outRect: Rect,
+        view: View,
+        parent: RecyclerView,
+        state: RecyclerView.State
+    ) {
+        with(outRect) {
+            if (parent.getChildAdapterPosition(view) == 0) {
+                top = size
+            }
+            left = size
+            right = size
+            bottom = size
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/SelectableItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/SelectableItem.kt
new file mode 100644
index 000000000..bcb816f35
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/util/SelectableItem.kt
@@ -0,0 +1,9 @@
+package de.rki.coronawarnapp.contactdiary.util
+
+import de.rki.coronawarnapp.util.lists.HasStableId
+
+data class SelectableItem<T : HasStableId>(
+    val selected: Boolean,
+    val item: T,
+    override val stableId: Long = item.stableId
+) : HasStableId
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/ActivityBinder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/ActivityBinder.kt
index fcb08e3b1..be99bd064 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/ActivityBinder.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/ActivityBinder.kt
@@ -2,8 +2,6 @@ package de.rki.coronawarnapp.ui
 
 import dagger.Module
 import dagger.android.ContributesAndroidInjector
-import de.rki.coronawarnapp.contactdiary.ui.ContactDiaryActivity
-import de.rki.coronawarnapp.contactdiary.ui.ContactDiaryModule
 import de.rki.coronawarnapp.ui.launcher.LauncherActivity
 import de.rki.coronawarnapp.ui.launcher.LauncherActivityModule
 import de.rki.coronawarnapp.ui.main.MainActivity
@@ -22,7 +20,4 @@ abstract class ActivityBinder {
 
     @ContributesAndroidInjector(modules = [OnboardingActivityModule::class])
     abstract fun onboardingActivity(): OnboardingActivity
-
-    @ContributesAndroidInjector(modules = [ContactDiaryModule::class])
-    abstract fun contactDiaryActivity(): ContactDiaryActivity
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
index 9e23785a4..6a81216b0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt
@@ -9,7 +9,7 @@ import de.rki.coronawarnapp.appconfig.AppConfigModule
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
 import de.rki.coronawarnapp.bugreporting.BugReporter
 import de.rki.coronawarnapp.bugreporting.BugReportingModule
-import de.rki.coronawarnapp.contactdiary.ContactDiaryModule
+import de.rki.coronawarnapp.contactdiary.ContactDiaryRootModule
 import de.rki.coronawarnapp.diagnosiskeys.DiagnosisKeysModule
 import de.rki.coronawarnapp.diagnosiskeys.DownloadDiagnosisKeysTaskModule
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
@@ -70,7 +70,7 @@ import javax.inject.Singleton
         BugReportingModule::class,
         SerializationModule::class,
         WorkerBinder::class,
-        ContactDiaryModule::class
+        ContactDiaryRootModule::class
     ]
 )
 interface ApplicationComponent : AndroidInjector<CoronaWarnApplication> {
diff --git a/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_locations.xml b/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_locations.xml
new file mode 100644
index 000000000..f5249e0bf
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_locations.xml
@@ -0,0 +1,23 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="200dp"
+    android:height="200dp"
+    android:viewportWidth="200"
+    android:viewportHeight="200">
+  <group>
+    <clip-path android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" />
+    <path
+        android:fillColor="#333337"
+        android:pathData="M-9.091,-6.818h224.242v257.576h-224.242z" />
+    <path
+        android:fillColor="#2B2B2D"
+        android:fillType="evenOdd"
+        android:pathData="M123.056,77.044L122.85,129.087H105.802V124.166H51.935V116.945H19.715V140.922H8.134V149.907H-40V208H-21.569H-3.443H8.134H19.715H26.26H64.019V207.823H100.77V208H125.436H137.272H170.549H172.957H184.967H203.524H226.846H233.365H261.227H272.254H291.063V198.63L349,206.658V146.985H291.063V114.886H272.254V106.935H226.846V118.06H211.78V102.174H184.967V77L123.056,77.044Z" />
+    <path
+        android:fillColor="#747576"
+        android:pathData="M100,39C76.227,39 57,58.093 57,81.7C57,113.725 100,161 100,161C100,161 143,113.725 143,81.7C143,58.093 123.773,39 100,39ZM100,96.95C91.523,96.95 84.643,90.118 84.643,81.7C84.643,73.282 91.523,66.45 100,66.45C108.477,66.45 115.357,73.282 115.357,81.7C115.357,90.118 108.477,96.95 100,96.95Z" />
+    <path
+        android:fillColor="#3F3F43"
+        android:fillType="evenOdd"
+        android:pathData="M112.677,163.277C76.438,163.277 60.651,141.575 26.816,145.683C18.774,146.66 8.561,149.711 -2.909,158.268V212.582L375.514,213.931V166.239C373.414,165.038 371.319,164.012 369.336,163.262C369.336,163.262 331.203,148.534 288.973,161.136C252.802,171.94 211.135,143.661 191.174,142.928C189.31,142.859 187.511,142.827 185.783,142.827C142.656,142.824 140.594,163.277 112.677,163.277Z" />
+  </group>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_people.xml b/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_people.xml
new file mode 100644
index 000000000..9d7916d3e
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable-night/ic_illustration_no_people.xml
@@ -0,0 +1,75 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="200dp"
+    android:height="200dp"
+    android:viewportWidth="200"
+    android:viewportHeight="200">
+    <group>
+        <clip-path android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" />
+        <path
+            android:fillColor="#2D2D2F"
+            android:pathData="M-9.091,-6.818h224.242v257.576h-224.242z" />
+        <path
+            android:fillColor="#3F3F43"
+            android:fillType="evenOdd"
+            android:pathData="M-31.146,141.336C-83.144,141.336 -105.797,110.204 -154.347,116.098C-165.887,117.499 -180.542,121.876 -197,134.151V212.065L346,214V145.585C342.986,143.863 339.98,142.391 337.135,141.314C337.135,141.314 282.418,120.186 221.821,138.264C169.92,153.763 110.133,113.197 81.49,112.145C78.816,112.046 76.234,112 73.754,112C11.872,111.996 8.913,141.336 -31.146,141.336Z" />
+        <path
+            android:fillColor="#333337"
+            android:fillType="evenOdd"
+            android:pathData="M20.842,73.288C15.227,73.431 12.013,81.43 11.745,85.229C10.601,101.491 0.658,113.088 1.579,138.418C2.182,155.016 8,172.068 14.153,175.053C26.002,180.802 33.951,167.998 35.288,156.057C36.626,144.117 37.428,126.749 28.6,105.039C23.698,92.984 32.086,73.001 20.842,73.288Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M17.012,119.964C16.994,119.943 10.349,112.043 10.795,106.151L11.404,106.201C10.979,111.826 17.459,119.523 17.475,119.544L17.012,119.964Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M20.399,177.094C19.353,172.585 17.004,149.987 16.942,125.523C16.905,110.67 17.708,95.122 20.158,82.504L20.817,82.624C18.376,95.201 17.575,110.707 17.612,125.523C17.674,149.936 20.011,172.463 21.053,176.952L20.399,177.094Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M17.641,148.7C17.665,148.659 25.378,135.949 26.567,130.827L27.223,130.971C26.01,136.193 18.244,148.991 18.219,149.033L17.641,148.7Z" />
+        <path
+            android:fillColor="#333337"
+            android:fillType="evenOdd"
+            android:pathData="M53.811,180.104C59.227,174.076 63.096,164.64 60.001,144.982C56.905,125.324 54.326,120.868 49.428,120.082C44.528,119.296 41.433,122.441 40.143,129.256C38.854,136.071 39.112,142.885 37.049,145.506C34.986,148.127 23.124,162.805 29.828,175.386C36.533,187.967 47.88,184.56 53.811,180.104Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M40.205,184.142C41.997,180.218 45.421,169.493 47.584,157.563C49.035,149.562 49.921,141.012 49.37,133.599L48.734,133.643C49.28,141.003 48.4,149.497 46.958,157.451C44.805,169.325 41.403,179.984 39.625,183.878L40.205,184.142Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M45.584,166.565C45.179,167.02 54.675,160.761 56.473,154.589L55.881,154.413C54.151,160.352 45.595,165.755 45.571,165.772L45.584,166.565Z" />
+        <path
+            android:fillColor="#1E1E1F"
+            android:fillType="evenOdd"
+            android:pathData="M42.598,177.794C42.582,177.772 37.066,170.055 36.239,164.323L35.661,164.424C36.512,170.331 42.121,178.175 42.137,178.197L42.598,177.794Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M105.519,81.291L115.162,95.661C115.162,95.661 120.519,100.476 116.844,102.233C113.172,103.99 112.404,97.19 112.404,97.19L105.288,90.31L105.519,81.291Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M75.389,164.357L73.138,168.626C72.827,169.214 73.035,169.939 73.609,170.276C76.328,171.859 83.762,175.905 86.969,174.817C87.42,174.663 87.529,174.077 87.18,173.755C85.133,171.873 78.769,165.869 79.26,164.396L75.389,164.357Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M75.182,164.753L79.533,165.333L101.049,115.716L89.845,93.238L89.715,124.004C89.715,124.004 79.722,143.843 78.126,151.626C76.55,159.311 75.182,164.753 75.182,164.753Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M89.141,86.062L106.025,86.287C106.025,86.287 120.659,159.583 126.511,164.529L123.36,166.777C123.36,166.777 105.35,142.27 106.925,126.53C106.925,126.53 84.639,90.783 89.141,86.062Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M101.055,57.863L99.971,50.202C99.971,50.202 104.686,50.412 104.58,43.839C104.559,42.621 104.473,40.538 103.348,38.956L99.136,37.74L96.302,46.289L94.084,57.085L98.304,59.777L101.473,59.694L101.055,57.863Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M123.356,166.777L124.049,171.551C124.144,172.208 124.74,172.675 125.403,172.607C128.533,172.29 136.927,171.193 138.879,168.427C139.151,168.04 138.896,167.498 138.422,167.445C135.659,167.126 126.976,166.014 126.505,164.532L123.356,166.777Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M85.468,96.196L86.644,81.855L92.715,83.586L88.453,98.337C88.453,98.337 87.381,106.898 83.785,104.375C79.319,101.242 85.314,97.953 85.468,96.196Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M86.614,82.063C86.614,82.063 86.623,81.992 86.641,81.855C86.961,79.504 89.958,58.056 93.322,57.195C96.879,56.281 98.689,59.659 100.315,57.831C101.941,56.003 111.507,71.124 106.022,86.29L91.963,86.304L96.675,65.217L92.712,83.592C92.712,83.586 87.633,84.905 86.614,82.063Z" />
+        <path
+            android:fillColor="#747576"
+            android:pathData="M104.574,43.825C104.574,43.825 107.974,41.707 105.723,35.876C105.723,35.876 105.222,33.377 101.722,33.463C101.722,33.463 96.136,28.467 90.882,32.714C85.628,36.962 89.215,41.207 89.215,41.207C89.215,41.207 82.21,47.537 84.63,56.115C84.63,56.115 87.215,61.694 90.216,59.78C93.219,57.863 93.05,62.028 94.634,56.449C96.219,50.87 98.97,51.702 97.886,42.292C97.886,42.292 101.639,42.541 102.471,38.71C102.471,38.71 104.592,39.509 104.574,43.825Z" />
+    </group>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_locations.xml b/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_locations.xml
new file mode 100644
index 000000000..7a57c9a75
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_locations.xml
@@ -0,0 +1,23 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="200dp"
+    android:height="200dp"
+    android:viewportWidth="200"
+    android:viewportHeight="200">
+  <group>
+    <clip-path android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" />
+    <path
+        android:fillColor="#E8F5FF"
+        android:pathData="M-9.091,-6.818h224.242v257.576h-224.242z" />
+    <path
+        android:fillColor="#B8E0FA"
+        android:fillType="evenOdd"
+        android:pathData="M123.056,77.044L122.85,129.087H105.802V124.166H51.935V116.945H19.715V140.922H8.134V149.907H-40V208H-21.569H-3.443H8.134H19.715H26.26H64.019V207.823H100.77V208H125.436H137.272H170.549H172.957H184.967H203.524H226.846H233.365H261.227H272.254H291.063V198.63L349,206.658V146.985H291.063V114.886H272.254V106.935H226.846V118.06H211.78V102.174H184.967V77L123.056,77.044Z" />
+    <path
+        android:fillColor="#ffffff"
+        android:pathData="M100,39C76.227,39 57,58.093 57,81.7C57,113.725 100,161 100,161C100,161 143,113.725 143,81.7C143,58.093 123.773,39 100,39ZM100,96.95C91.523,96.95 84.643,90.118 84.643,81.7C84.643,73.282 91.523,66.45 100,66.45C108.477,66.45 115.357,73.282 115.357,81.7C115.357,90.118 108.477,96.95 100,96.95Z" />
+    <path
+        android:fillColor="#D8ECF9"
+        android:fillType="evenOdd"
+        android:pathData="M112.677,163.277C76.438,163.277 60.651,141.575 26.816,145.683C18.774,146.66 8.561,149.711 -2.909,158.268V212.582L375.514,213.931V166.239C373.414,165.038 371.319,164.012 369.336,163.262C369.336,163.262 331.203,148.534 288.973,161.136C252.802,171.94 211.135,143.661 191.174,142.928C189.31,142.859 187.511,142.827 185.783,142.827C142.656,142.824 140.594,163.277 112.677,163.277Z" />
+  </group>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_people.xml b/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_people.xml
new file mode 100644
index 000000000..10c43a63c
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_illustration_no_people.xml
@@ -0,0 +1,62 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="200dp"
+    android:height="200dp"
+    android:viewportWidth="200"
+    android:viewportHeight="200">
+    <group>
+        <clip-path android:pathData="M100,100m-100,0a100,100 0,1 1,200 0a100,100 0,1 1,-200 0" />
+        <path
+            android:fillColor="#E8F5FF"
+            android:pathData="M-9.091,-6.818h224.242v257.576H-9.091z" />
+        <path
+            android:fillColor="#D8ECF9"
+            android:fillType="evenOdd"
+            android:pathData="M-31.146,141.336c-51.998,0 -74.651,-31.132 -123.201,-25.238 -11.54,1.401 -26.195,5.778 -42.653,18.053v77.914L346,214v-68.415c-3.014,-1.722 -6.02,-3.194 -8.865,-4.271 0,0 -54.717,-21.128 -115.314,-3.05 -51.901,15.499 -111.688,-25.067 -140.331,-26.119a209.205,209.205 0,0 0,-7.736 -0.145c-61.882,-0.004 -64.841,29.336 -104.9,29.336z" />
+        <path
+            android:fillColor="#B8E0FA"
+            android:fillType="evenOdd"
+            android:pathData="M20.842,73.288c-5.615,0.143 -8.829,8.142 -9.097,11.94 -1.144,16.263 -11.087,27.86 -10.166,53.19 0.603,16.598 6.42,33.65 12.574,36.635 11.849,5.749 19.797,-7.055 21.135,-18.996 1.338,-11.94 2.14,-29.308 -6.688,-51.018 -4.902,-12.055 3.486,-32.038 -7.758,-31.751z" />
+        <path
+            android:fillColor="#fff"
+            android:fillType="evenOdd"
+            android:pathData="M17.012,119.964c-0.018,-0.021 -6.663,-7.921 -6.217,-13.813l0.609,0.05c-0.425,5.625 6.055,13.322 6.07,13.343l-0.462,0.42z" />
+        <path
+            android:fillColor="#fff"
+            android:fillType="evenOdd"
+            android:pathData="M20.399,177.094c-1.046,-4.509 -3.395,-27.107 -3.457,-51.571 -0.037,-14.853 0.766,-30.401 3.216,-43.02l0.659,0.12c-2.441,12.578 -3.242,28.084 -3.205,42.9 0.062,24.413 2.4,46.94 3.44,51.429l-0.653,0.142z" />
+        <path
+            android:fillColor="#fff"
+            android:fillType="evenOdd"
+            android:pathData="M17.64,148.7c0.025,-0.04 7.738,-12.751 8.927,-17.873l0.656,0.144c-1.213,5.222 -8.979,18.02 -9.004,18.062l-0.578,-0.333z" />
+        <path
+            android:fillColor="#B8E0FA"
+            android:fillType="evenOdd"
+            android:pathData="M53.81,180.104c5.417,-6.028 9.285,-15.464 6.191,-35.122 -3.095,-19.658 -5.674,-24.114 -10.573,-24.9 -4.9,-0.786 -7.995,2.359 -9.285,9.174 -1.29,6.815 -1.03,13.629 -3.094,16.25 -2.063,2.621 -13.925,17.299 -7.221,29.88 6.705,12.581 18.052,9.174 23.983,4.718z" />
+        <path
+            android:fillColor="#fff"
+            android:fillType="evenOdd"
+            android:pathData="M40.205,184.142c1.792,-3.924 5.216,-14.649 7.38,-26.579 1.45,-8.001 2.336,-16.551 1.785,-23.964l-0.636,0.044c0.546,7.361 -0.334,15.854 -1.776,23.808 -2.154,11.874 -5.555,22.533 -7.332,26.427l0.579,0.264z" />
+        <path
+            android:fillColor="#fff"
+            android:fillType="evenOdd"
+            android:pathData="M45.584,166.565c-0.405,0.455 9.09,-5.804 10.889,-11.976l-0.593,-0.176c-1.729,5.939 -10.285,11.342 -10.31,11.359l0.014,0.793zM42.598,177.794c-0.016,-0.022 -5.532,-7.739 -6.359,-13.472l-0.578,0.102c0.85,5.907 6.46,13.751 6.476,13.773l0.46,-0.403z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M105.519,81.29l9.643,14.37s5.357,4.816 1.682,6.573c-3.672,1.757 -4.44,-5.043 -4.44,-5.043l-7.116,-6.88 0.231,-9.02zM75.39,164.357l-2.252,4.269a1.239,1.239 0,0 0,0.471 1.65c2.72,1.583 10.153,5.629 13.36,4.541 0.45,-0.154 0.56,-0.74 0.21,-1.062 -2.046,-1.882 -8.41,-7.886 -7.919,-9.359l-3.87,-0.039z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M75.182,164.754l4.35,0.579 21.517,-49.617 -11.204,-22.478 -0.13,30.766s-9.993,19.839 -11.589,27.622c-1.576,7.685 -2.944,13.128 -2.944,13.128z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M89.14,86.062l16.885,0.225s14.634,73.296 20.486,78.242l-3.151,2.248s-18.01,-24.507 -16.435,-40.247c0,0 -22.286,-35.747 -17.784,-40.468zM101.055,57.863l-1.084,-7.661s4.715,0.21 4.609,-6.363c-0.021,-1.218 -0.107,-3.3 -1.232,-4.883l-4.212,-1.216 -2.834,8.548 -2.219,10.797 4.22,2.692 3.17,-0.083 -0.418,-1.83z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M123.356,166.777l0.693,4.774a1.24,1.24 0,0 0,1.354 1.056c3.13,-0.317 11.524,-1.414 13.476,-4.18 0.272,-0.387 0.017,-0.929 -0.457,-0.982 -2.763,-0.319 -11.446,-1.431 -11.917,-2.913l-3.149,2.245zM85.468,96.196l1.175,-14.34 6.072,1.73 -4.262,14.751s-1.072,8.561 -4.668,6.038c-4.466,-3.133 1.529,-6.422 1.683,-8.18z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M86.614,82.063l0.027,-0.207c0.32,-2.352 3.317,-23.8 6.681,-24.661 3.557,-0.914 5.367,2.464 6.993,0.636 1.626,-1.828 11.192,13.293 5.707,28.459l-14.059,0.014 4.712,-21.087 -3.963,18.375c0,-0.006 -5.079,1.313 -6.098,-1.53z" />
+        <path
+            android:fillColor="#fff"
+            android:pathData="M104.574,43.825s3.4,-2.118 1.149,-7.949c0,0 -0.501,-2.5 -4.001,-2.413 0,0 -5.586,-4.996 -10.84,-0.749 -5.254,4.248 -1.667,8.493 -1.667,8.493s-7.005,6.33 -4.585,14.908c0,0 2.586,5.579 5.586,3.665 3.003,-1.917 2.834,2.248 4.418,-3.33 1.585,-5.58 4.336,-4.748 3.252,-14.158 0,0 3.753,0.249 4.585,-3.582 0,0 2.121,0.799 2.103,5.115z" />
+    </group>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_selected.xml b/Corona-Warn-App/src/main/res/drawable/ic_selected.xml
new file mode 100644
index 000000000..9e0e983be
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_selected.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="32"
+    android:viewportHeight="32">
+  <path
+      android:fillColor="#007FAD"
+      android:fillType="evenOdd"
+      android:pathData="M32,16.008C32,24.777 24.773,32 16,32S0,24.777 0,16.008C0,7.238 7.211,0 15.985,0 24.758,0 32,7.239 32,16.008zM12.342,23.29c0.444,0.536 0.949,0.827 1.592,0.827 0.612,0 1.164,-0.306 1.531,-0.873l7.778,-11.967c0.23,-0.367 0.398,-0.78 0.398,-1.148 0,-0.888 -0.78,-1.484 -1.623,-1.484 -0.551,0 -1.01,0.29 -1.393,0.887l-6.737,10.743 -3.506,-4.346c-0.398,-0.474 -0.812,-0.689 -1.332,-0.689 -0.858,0 -1.577,0.69 -1.577,1.577 0,0.413 0.153,0.81 0.459,1.178l4.41,5.295z" />
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_unselected.xml b/Corona-Warn-App/src/main/res/drawable/ic_unselected.xml
new file mode 100644
index 000000000..75f82140f
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_unselected.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="34dp"
+    android:height="34dp"
+    android:viewportWidth="34"
+    android:viewportHeight="34">
+  <path
+      android:fillColor="#00000000"
+      android:pathData="M17,17m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
+      android:strokeWidth="1"
+      android:strokeColor="#007FAD" />
+</vector>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_activity.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_activity.xml
index cff3bed3f..f105f4d50 100644
--- a/Corona-Warn-App/src/main/res/layout/contact_diary_activity.xml
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_activity.xml
@@ -14,4 +14,4 @@
         app:defaultNavHost="true"
         app:navGraph="@navigation/contact_diary_nav_graph" />
 
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml
new file mode 100644
index 000000000..f0de56a4c
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:contentDescription="@string/settings_title"
+        android:focusable="true">
+
+        <include
+            android:id="@+id/contact_diary_day_header"
+            layout="@layout/include_header"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            app:icon="@{@drawable/ic_back}"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:title="@{@string/settings_title}" />
+
+        <com.google.android.material.tabs.TabLayout
+            android:id="@+id/contact_diary_day_tab_layout"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_day_header" />
+
+        <androidx.viewpager2.widget.ViewPager2
+            android:id="@+id/contact_diary_day_view_pager"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="@dimen/match_constraint"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_day_tab_layout" />
+
+        <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+            android:id="@+id/contact_diary_day_fab"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/spacing_normal"
+            style="@style/Widget.App.ExtendedFloatingActionButton"
+            android:text="@string/contact_diary_day_person_fab_title"
+            app:icon="@android:drawable/ic_input_add"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_location_bottom_sheet_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_location_bottom_sheet_fragment.xml
new file mode 100644
index 000000000..8a2c25860
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_location_bottom_sheet_fragment.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <include
+            android:id="@+id/contact_diary_location_bottom_sheet_close_button"
+            layout="@layout/include_button_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_small"
+            app:icon="@{@drawable/ic_close}"
+            app:iconDescription="@{@string/accessibility_close}"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/contact_diary_location_bottom_sheet_title"
+            style="@style/headline6"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_normal"
+            android:text="@string/contact_diary_location_bottom_sheet_title"
+            app:layout_constraintBottom_toBottomOf="@+id/contact_diary_location_bottom_sheet_close_button"
+            app:layout_constraintStart_toEndOf="@+id/contact_diary_location_bottom_sheet_close_button"
+            app:layout_constraintTop_toTopOf="@+id/contact_diary_location_bottom_sheet_close_button" />
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/contact_diary_location_bottom_sheet_text_input_layout"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_small"
+            android:hint="@string/contact_diary_location_bottom_sheet_text_input_hint"
+            app:counterEnabled="true"
+            app:counterMaxLength="250"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_location_bottom_sheet_close_button">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/contact_diary_location_bottom_sheet_text_input_edit_text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <Button
+            android:id="@+id/contact_diary_location_bottom_sheet_save_button"
+            style="@style/buttonPrimary"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_normal"
+            android:layout_marginBottom="@dimen/spacing_small"
+            android:text="@string/contact_diary_location_bottom_sheet_save_button"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_location_bottom_sheet_text_input_layout" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_fragment.xml
new file mode 100644
index 000000000..9d491caba
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_fragment.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/contact_diary_location_list_recycler_view"
+            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="@dimen/match_constraint"
+            android:layout_margin="@dimen/spacing_normal"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.constraintlayout.widget.Group
+            android:id="@+id/contact_diary_location_list_no_items_group"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:constraint_referenced_ids="contact_diary_location_list_no_items_image,contact_diary_location_list_no_items_title,contact_diary_location_list_no_items_subtitle" />
+
+        <ImageView
+            android:id="@+id/contact_diary_location_list_no_items_image"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_location_list_no_items_title"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:srcCompat="@drawable/ic_illustration_no_locations" />
+
+        <TextView
+            android:id="@+id/contact_diary_location_list_no_items_title"
+            style="@style/subtitleMedium"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_huge"
+            android:layout_marginTop="@dimen/spacing_normal"
+            android:text="@string/contact_diary_location_list_no_items_title"
+            android:textAlignment="center"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_location_list_no_items_subtitle"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_location_list_no_items_image" />
+
+        <TextView
+            android:id="@+id/contact_diary_location_list_no_items_subtitle"
+            style="@style/body2Medium"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_huge"
+            android:layout_marginTop="@dimen/spacing_tiny"
+            android:text="@string/contact_diary_location_list_no_items_subtitle"
+            android:textAlignment="center"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_location_list_no_items_title" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_line.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_line.xml
new file mode 100644
index 000000000..0023574f3
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_location_list_line.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="60dp"
+        android:background="@color/colorSurface2">
+
+        <ImageView
+            android:id="@+id/contact_diary_location_list_line_icon"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:layout_marginStart="@dimen/spacing_small"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:srcCompat="@drawable/ic_selected" />
+
+        <TextView
+            android:id="@+id/contact_diary_location_list_line_name"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_small"
+            android:layout_marginVertical="@dimen/spacing_small"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/contact_diary_location_list_line_icon"
+            app:layout_constraintTop_toTopOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_person_bottom_sheet_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_person_bottom_sheet_fragment.xml
new file mode 100644
index 000000000..8cfcbf0ff
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_person_bottom_sheet_fragment.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <include
+            android:id="@+id/contact_diary_person_bottom_sheet_close_button"
+            layout="@layout/include_button_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_small"
+            app:icon="@{@drawable/ic_close}"
+            app:iconDescription="@{@string/accessibility_close}"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/contact_diary_person_bottom_sheet_title"
+            style="@style/headline6"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_normal"
+            android:text="@string/contact_diary_person_bottom_sheet_title"
+            app:layout_constraintBottom_toBottomOf="@+id/contact_diary_person_bottom_sheet_close_button"
+            app:layout_constraintStart_toEndOf="@+id/contact_diary_person_bottom_sheet_close_button"
+            app:layout_constraintTop_toTopOf="@+id/contact_diary_person_bottom_sheet_close_button" />
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/contact_diary_person_bottom_sheet_text_input_layout"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_small"
+            app:counterEnabled="true"
+            app:counterMaxLength="250"
+            android:hint="@string/contact_diary_person_bottom_sheet_text_input_hint"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_person_bottom_sheet_close_button">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/contact_diary_person_bottom_sheet_text_input_edit_text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <Button
+            android:id="@+id/contact_diary_person_bottom_sheet_save_button"
+            style="@style/buttonPrimary"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_normal"
+            android:layout_marginTop="@dimen/spacing_normal"
+            android:layout_marginBottom="@dimen/spacing_small"
+            android:text="@string/contact_diary_person_bottom_sheet_save_button"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_person_bottom_sheet_text_input_layout" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_fragment.xml
new file mode 100644
index 000000000..47f1a6197
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_fragment.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/contact_diary_person_list_recycler_view"
+            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="@dimen/match_constraint"
+            android:layout_margin="@dimen/spacing_normal"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <androidx.constraintlayout.widget.Group
+            android:id="@+id/contact_diary_person_list_no_items_group"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:constraint_referenced_ids="contact_diary_person_list_no_items_image,contact_diary_person_list_no_items_title,contact_diary_person_list_no_items_subtitle" />
+
+        <ImageView
+            android:id="@+id/contact_diary_person_list_no_items_image"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_person_list_no_items_title"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            app:srcCompat="@drawable/ic_illustration_no_people" />
+
+        <TextView
+            android:id="@+id/contact_diary_person_list_no_items_title"
+            style="@style/subtitleMedium"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_huge"
+            android:layout_marginTop="@dimen/spacing_normal"
+            android:text="@string/contact_diary_person_list_no_items_title"
+            android:textAlignment="center"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_person_list_no_items_subtitle"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_person_list_no_items_image" />
+
+        <TextView
+            android:id="@+id/contact_diary_person_list_no_items_subtitle"
+            style="@style/body2Medium"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_huge"
+            android:layout_marginTop="@dimen/spacing_tiny"
+            android:text="@string/contact_diary_person_list_no_items_subtitle"
+            android:textAlignment="center"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_person_list_no_items_title" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_line.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_line.xml
new file mode 100644
index 000000000..9f364109a
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_person_list_line.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="60dp"
+        android:background="@color/colorSurface2">
+
+        <ImageView
+            android:id="@+id/contact_diary_person_list_line_icon"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:layout_marginStart="@dimen/spacing_small"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:srcCompat="@drawable/ic_selected" />
+
+        <TextView
+            android:id="@+id/contact_diary_person_list_line_name"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/spacing_small"
+            android:layout_marginVertical="@dimen/spacing_small"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/contact_diary_person_list_line_icon"
+            app:layout_constraintTop_toTopOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
diff --git a/Corona-Warn-App/src/main/res/navigation/contact_diary_nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/contact_diary_nav_graph.xml
index 80999eff0..c5ceb7671 100644
--- a/Corona-Warn-App/src/main/res/navigation/contact_diary_nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/contact_diary_nav_graph.xml
@@ -4,10 +4,49 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/contact_diary_nav_graph"
     app:startDestination="@id/contactDiaryOnboardingFragment">
+    <fragment
+        android:id="@+id/contactDiaryDayFragment"
+        android:name="de.rki.coronawarnapp.contactdiary.ui.day.ContactDiaryDayFragment"
+        android:label="ContactDiaryDayFragment">
+        <argument
+            android:name="selectedDay"
+            android:defaultValue="2020-03-25"
+            app:argType="string" />
+        <action
+            android:id="@+id/action_contactDiaryDayFragment_to_contactDiaryPersonBottomSheetDialogFragment"
+            app:destination="@id/contactDiaryPersonBottomSheetDialogFragment" />
+        <action
+            android:id="@+id/action_contactDiaryDayFragment_to_contactDiaryLocationBottomSheetDialogFragment"
+            app:destination="@id/contactDiaryLocationBottomSheetDialogFragment" />
+    </fragment>
+    <fragment
+        android:id="@+id/contactDiaryPersonListFragment"
+        android:name="de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.ContactDiaryPersonListFragment"
+        android:label="ContactDiaryPersonListFragment">
+        <argument
+            android:name="selectedDay"
+            app:argType="string" />
+    </fragment>
+    <fragment
+        android:id="@+id/contactDiaryPlaceListFragment"
+        android:name="de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.ContactDiaryLocationListFragment"
+        android:label="ContactDiaryPlaceListFragment">
+        <argument
+            android:name="selectedDay"
+            app:argType="string" />
+    </fragment>
+    <dialog
+        android:id="@+id/contactDiaryPersonBottomSheetDialogFragment"
+        android:name="de.rki.coronawarnapp.contactdiary.ui.day.sheets.person.ContactDiaryPersonBottomSheetDialogFragment"
+        android:label="ContactDiaryPersonBottomSheetDialogFragment" />
+    <dialog
+        android:id="@+id/contactDiaryLocationBottomSheetDialogFragment"
+        android:name="de.rki.coronawarnapp.contactdiary.ui.day.sheets.location.ContactDiaryLocationBottomSheetDialogFragment"
+        android:label="ContactDiaryLocationBottomSheetDialogFragment" />
     <fragment
         android:id="@+id/contactDiaryOnboardingFragment"
         android:name="de.rki.coronawarnapp.contactdiary.ui.onboarding.ContactDiaryOnboardingFragment"
-        android:label="ContactDiaryOnboardingFragment" >
+        android:label="ContactDiaryOnboardingFragment">
         <action
             android:id="@+id/action_contactDiaryOnboardingFragment_to_contactDiaryInformationPrivacyFragment"
             app:destination="@id/contactDiaryInformationPrivacyFragment" />
@@ -23,5 +62,9 @@
         android:id="@+id/contactDiaryOverviewFragment"
         android:name="de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragment"
         android:label="contact_diary_overview_fragment"
-        tools:layout="@layout/contact_diary_overview_fragment" />
+        tools:layout="@layout/contact_diary_overview_fragment">
+        <action
+            android:id="@+id/action_contactDiaryOverviewFragment_to_contactDiaryDayFragment"
+            app:destination="@id/contactDiaryDayFragment" />
+    </fragment>
 </navigation>
diff --git a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
index d696d648c..836d1fe87 100644
--- a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml
@@ -3,21 +3,20 @@
     <!-- ####################################
                 Contact Diary
     ###################################### -->
-    <string name="contact_diary_day_person_tab_title">"Personen"</string>
-    <string name="contact_diary_day_person_fab_title">"Person"</string>
-    <string name="contact_diary_day_location_tab_title">"Orte"</string>
-    <string name="contact_diary_day_location_fab_title">"Ort"</string>
-    <string name="contact_diary_location_list_no_items_title">"Noch keine Orte vorhanden"</string>
-    <string name="contact_diary_location_list_no_items_subtitle">"Legen Sie einen Ort an und fügen Sie ihn in Ihrem Kontakt-Tagebuch hinzu."</string>
-    <string name="contact_diary_person_list_no_items_title">"Noch keine Personen vorhanden"</string>
-    <string name="contact_diary_person_list_no_items_subtitle">"Legen Sie eine Person an und fügen Sie sie in Ihrem Kontakt-Tagebuch hinzu."</string>
-    <string name="contact_diary_person_bottom_sheet_title">"Person"</string>
-    <string name="contact_diary_person_bottom_sheet_text_input_hint">"Vorname, Nachname"</string>
-    <string name="contact_diary_person_bottom_sheet_save_button">"Speichern"</string>
-    <string name="contact_diary_location_bottom_sheet_title">"Ort"</string>
-    <string name="contact_diary_location_bottom_sheet_text_input_hint">"Bezeichnung"</string>
-    <string name="contact_diary_location_bottom_sheet_save_button">"Speichern"</string>
-
+    <string name="contact_diary_day_person_tab_title"></string>
+    <string name="contact_diary_day_person_fab_title"></string>
+    <string name="contact_diary_day_location_tab_title"></string>
+    <string name="contact_diary_day_location_fab_title"></string>
+    <string name="contact_diary_location_list_no_items_title"></string>
+    <string name="contact_diary_location_list_no_items_subtitle"></string>
+    <string name="contact_diary_person_list_no_items_title"></string>
+    <string name="contact_diary_person_list_no_items_subtitle"></string>
+    <string name="contact_diary_person_bottom_sheet_title"></string>
+    <string name="contact_diary_person_bottom_sheet_text_input_hint"></string>
+    <string name="contact_diary_person_bottom_sheet_save_button"></string>
+    <string name="contact_diary_location_bottom_sheet_title"></string>
+    <string name="contact_diary_location_bottom_sheet_text_input_hint"></string>
+    <string name="contact_diary_location_bottom_sheet_save_button"></string>
     <!-- XHED: Title for the contact diary card displayed in the homescreen -->
     <string name="contact_diary_homescreen_card_header" />
     <!-- XTXT: Body for the contact diary card displayed in the homescreen  -->
diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml
index f52ee4665..7670cb51b 100644
--- a/Corona-Warn-App/src/main/res/values/styles.xml
+++ b/Corona-Warn-App/src/main/res/values/styles.xml
@@ -12,10 +12,36 @@
         <item name="windowNoTitle">true</item>
     </style>
 
+    <style name="MaterialAppTheme" parent="Theme.MaterialComponents.DayNight">
+        <item name="colorPrimary">@color/colorBrandSecondary</item>
+        <item name="colorPrimaryDark">@color/colorStableDark</item>
+        <item name="android:windowBackground">@color/colorBackground</item>
+        <item name="alertDialogTheme">@style/dialog</item>
+    </style>
+
+    <style name="MaterialAppTheme.NoActionBar" parent="MaterialAppTheme">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
     <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
 
     <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
 
+    <style name="AppTheme.ContactDiary" parent="MaterialAppTheme.NoActionBar" />
+
+    <style name="ThemeOverlay.App.ExtendedFloatingActionButton" parent="">
+        <item name="colorSecondary">@color/colorAccentTintButton</item>
+        <item name="colorOnSecondary">@color/colorTextEmphasizedButton</item>
+        <item name="colorOnSurface">@color/colorAccentTintButtonPressed</item>
+    </style>
+
+    <style name="Widget.App.ExtendedFloatingActionButton" parent="Widget.MaterialComponents.ExtendedFloatingActionButton.Icon">
+        <item name="materialThemeOverlay">
+            @style/ThemeOverlay.App.ExtendedFloatingActionButton
+        </item>
+    </style>
+
     <!-- Launcher theme with background -->
     <style name="AppTheme.Launcher" parent="AppTheme.NoActionBar">
         <item name="android:windowBackground">@drawable/splash_screen</item>
-- 
GitLab