From 93c7b1767e03cd29889f1add5c2e7eb5d808e92b Mon Sep 17 00:00:00 2001
From: BMItter <46747780+BMItter@users.noreply.github.com>
Date: Tue, 15 Dec 2020 21:00:27 +0100
Subject: [PATCH] Contact Diary - Overview Screen, Calender (Draft,
 EXPOSUREAPP-4155) (#1892)

* Added basic layout

* Added translation support

* Added darkmode images

* Included dimens in layout

* Added navigation to onboarding fragment

* Changed AndroidManifest to support new contact diary activity

* Updated translation files

* Added missing image
Updated text styling
Changed layout naming

* Added back navigation

* Updated layout

* Added direct link to privacy information

* repair PR commit

* Changed back navigation

* repair

* skeleton for overview / calender view

* Added classes to display the overview fragment
Connected overview to onboarding fragment

* Added missing classes

* Added basic overview layout

* Added list element
Added new icons for light and dark mode

* Added missing icons

* Added recycler view adapter

* Added icons for list items

* added layout for nested recycler view

* Replaced leftovers of ContactDiaryElement with ListItem

* Added toolbar menu

* Added back navigation to home screen

* Changed layout to dimens

* Combine data to list items

* Show locations and persons

* sourceCheck & lint clean

* List item data as inner class

* Fixed nested layout

* Created nested recycler view for person and location data

* Added pseudo navigation

* changed inject position to the top

* removed comment from layout

* Added const val for count of days to boost the quality

* Remove unused xml
removed cast
removed unused method from ContactDiaryActivity

* Aligned Adapters to avoid confusion overload

* cleaned

* Updated layout

* Added strings

* fixed merge deletion

* fix recycler height

* added little scrollbar to recycler

* little bit more space to top element

* Updated layout

* Created storage module for storage related stuff

* Updated list items

Remove return statement

Co-authored-by: I502720 <axel.herbstreith@sap.com>
---
 .../contactdiary/ContactDiaryModule.kt        | 43 +--------
 .../storage/ContactDiaryStorageModule.kt      | 40 ++++++++
 .../contactdiary/ui/ContactDiaryModule.kt     |  5 +
 .../ContactDiaryOnboardingFragment.kt         | 12 +++
 .../ContactDiaryOnboardingFragmentModul.kt    | 23 +++++
 ...ContactDiaryOnboardingFragmentViewModel.kt |  2 +-
 .../ContactDiaryOnboardingNavigationEvents.kt |  1 +
 .../overview/ContactDiaryOverviewFragment.kt  | 69 +++++++++++++
 .../ContactDiaryOverviewFragmentModule.kt     | 23 +++++
 .../ui/overview/ContactDiaryOverviewMenu.kt   | 31 ++++++
 .../ContactDiaryOverviewNavigationEvents.kt   | 11 +++
 .../overview/ContactDiaryOverviewViewModel.kt | 96 +++++++++++++++++++
 .../adapter/ContactDiaryOverviewAdapter.kt    | 63 ++++++++++++
 .../ContactDiaryOverviewNestedAdapter.kt      | 37 +++++++
 .../ui/overview/adapter/ListItem.kt           | 14 +++
 .../ic_contact_diary_location_item.xml        | 12 +++
 .../ic_contact_diary_person_item.xml          | 12 +++
 .../ic_contact_diary_right_arrow.xml          | 10 ++
 .../ic_contact_diary_location_item.xml        | 12 +++
 .../drawable/ic_contact_diary_person_item.xml | 12 +++
 .../drawable/ic_contact_diary_right_arrow.xml | 11 +++
 .../contact_diary_overview_fragment.xml       | 85 ++++++++++++++++
 .../include_contact_diary_overview_header.xml | 78 +++++++++++++++
 .../include_contact_diary_overview_item.xml   | 59 ++++++++++++
 ...ude_contact_diary_overview_nested_item.xml | 47 +++++++++
 .../res/menu/menu_contact_diary_overview.xml  | 15 +++
 .../navigation/contact_diary_nav_graph.xml    |  9 ++
 .../res/values-de/contact_diary_strings.xml   | 15 +++
 .../main/res/values/contact_diary_strings.xml | 15 +++
 .../src/main/res/values/dimens.xml            |  3 +
 .../src/main/res/values/styles.xml            |  9 ++
 31 files changed, 835 insertions(+), 39 deletions(-)
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryStorageModule.kt
 create 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/ui/overview/ContactDiaryOverviewFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
 create mode 100644 Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_location_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_person_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_right_arrow.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_contact_diary_location_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_contact_diary_person_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_contact_diary_right_arrow.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_header.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_nested_item.xml
 create mode 100644 Corona-Warn-App/src/main/res/menu/menu_contact_diary_overview.xml

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
index b32ac7a95..e2529d15f 100644
--- 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
@@ -1,42 +1,9 @@
 package de.rki.coronawarnapp.contactdiary
 
 import dagger.Module
-import dagger.Provides
-import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase
-import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationDao
-import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationVisitDao
-import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonDao
-import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonEncounterDao
-import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
-import de.rki.coronawarnapp.contactdiary.storage.repo.DefaultContactDiaryRepository
-import javax.inject.Singleton
+import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryStorageModule
 
-@Module
-class ContactDiaryModule {
-
-    @Singleton
-    @Provides
-    fun contactDiaryDatabase(contactDiaryDatabaseFactory: ContactDiaryDatabase.Factory): ContactDiaryDatabase =
-        contactDiaryDatabaseFactory.create()
-
-    @Provides
-    fun locationDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationDao =
-        contactDiaryDatabase.locationDao()
-
-    @Provides
-    fun locationVisitDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationVisitDao =
-        contactDiaryDatabase.locationVisitDao()
-
-    @Provides
-    fun personDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonDao =
-        contactDiaryDatabase.personDao()
-
-    @Provides
-    fun personEncounterDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonEncounterDao =
-        contactDiaryDatabase.personEncounterDao()
-
-    @Singleton
-    @Provides
-    fun contactDiaryRepo(defaultContactDiaryRepository: DefaultContactDiaryRepository): ContactDiaryRepository =
-        defaultContactDiaryRepository
-}
+@Module(
+    includes = [ContactDiaryStorageModule::class]
+)
+class ContactDiaryModule
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryStorageModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryStorageModule.kt
new file mode 100644
index 000000000..8954837fc
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryStorageModule.kt
@@ -0,0 +1,40 @@
+package de.rki.coronawarnapp.contactdiary.storage
+
+import dagger.Module
+import dagger.Provides
+import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationDao
+import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationVisitDao
+import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonDao
+import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonEncounterDao
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.contactdiary.storage.repo.DefaultContactDiaryRepository
+import javax.inject.Singleton
+
+@Module
+class ContactDiaryStorageModule {
+    @Singleton
+    @Provides
+    fun contactDiaryDatabase(contactDiaryDatabaseFactory: ContactDiaryDatabase.Factory): ContactDiaryDatabase =
+        contactDiaryDatabaseFactory.create()
+
+    @Provides
+    fun locationDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationDao =
+        contactDiaryDatabase.locationDao()
+
+    @Provides
+    fun locationVisitDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationVisitDao =
+        contactDiaryDatabase.locationVisitDao()
+
+    @Provides
+    fun personDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonDao =
+        contactDiaryDatabase.personDao()
+
+    @Provides
+    fun personEncounterDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonEncounterDao =
+        contactDiaryDatabase.personEncounterDao()
+
+    @Singleton
+    @Provides
+    fun contactDiaryRepo(defaultContactDiaryRepository: DefaultContactDiaryRepository): ContactDiaryRepository =
+        defaultContactDiaryRepository
+}
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
index 9b3577952..8aca513cd 100644
--- 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
@@ -4,9 +4,14 @@ 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/onboarding/ContactDiaryOnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragment.kt
index 6dc68b561..065596dcd 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
@@ -51,7 +51,19 @@ class ContactDiaryOnboardingFragment : Fragment(R.layout.contact_diary_onboardin
                         )
                     )
                 }
+
+                ContactDiaryOnboardingNavigationEvents.NavigateToOverviewFragment -> {
+                    doNavigate(
+                        ActionOnlyNavDirections(
+                            R.id.action_contactDiaryOnboardingFragment_to_contactDiaryOverviewFragment
+                        )
+                    )
+                }
             }
         }
     }
+
+    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
new file mode 100644
index 000000000..0b338fb70
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentModul.kt
@@ -0,0 +1,23 @@
+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/ContactDiaryOnboardingFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentViewModel.kt
index e50e4a367..0edf3bfbb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/onboarding/ContactDiaryOnboardingFragmentViewModel.kt
@@ -9,7 +9,7 @@ class ContactDiaryOnboardingFragmentViewModel @AssistedInject constructor() : CW
     val routeToScreen: SingleLiveEvent<ContactDiaryOnboardingNavigationEvents> = SingleLiveEvent()
 
     fun onNextButtonClick() {
-        TODO("handle this")
+        routeToScreen.postValue(ContactDiaryOnboardingNavigationEvents.NavigateToOverviewFragment)
     }
 
     fun onBackButtonPress() {
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 138c7ce4c..62578f22e 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
@@ -4,4 +4,5 @@ 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
new file mode 100644
index 000000000..b68f69c5b
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt
@@ -0,0 +1,69 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.View
+import android.widget.Toast
+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.observe2
+import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
+
+class ContactDiaryOverviewFragment : Fragment(R.layout.contact_diary_overview_fragment), AutoInject {
+
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+    @Inject lateinit var contactDiaryOverviewMenu: ContactDiaryOverviewMenu
+    private val vm: ContactDiaryOverviewViewModel by cwaViewModels { viewModelFactory }
+    private val binding: ContactDiaryOverviewFragmentBinding by viewBindingLazy()
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        val adapter = ContactDiaryOverviewAdapter {
+            vm.onItemPress(it)
+        }
+
+        setupToolbar()
+
+        binding.apply {
+            contactDiaryOverviewRecyclerview.adapter = adapter
+
+            contactDiaryOverviewHeader.contactDiaryHeaderButtonBack.buttonIcon.setOnClickListener {
+                vm.onBackButtonPress()
+            }
+        }
+
+        vm.listItems.observe2(this) {
+            adapter.setItems(it)
+        }
+
+        vm.routeToScreen.observe2(this) {
+            when (it) {
+                ContactDiaryOverviewNavigationEvents.NavigateToMainActivity -> {
+                    requireActivity().finish()
+                }
+
+                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()
+                }
+            }
+        }
+    }
+
+    private fun setupToolbar() {
+
+        binding.contactDiaryOverviewHeader.contactDiaryHeaderOptionsMenu.buttonIcon.apply {
+            contentDescription = getString(R.string.button_menu)
+            setOnClickListener { contactDiaryOverviewMenu.showMenuFor(it) }
+        }
+    }
+}
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
new file mode 100644
index 000000000..23c65456c
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragmentModule.kt
@@ -0,0 +1,23 @@
+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
+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
new file mode 100644
index 000000000..e3827f479
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewMenu.kt
@@ -0,0 +1,31 @@
+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
+
+class ContactDiaryOverviewMenu @Inject constructor(
+    private val contactDiaryOverviewFragment: ContactDiaryOverviewFragment
+) {
+    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 {
+            when (it.itemId) {
+                R.id.menu_contact_diary_information -> { true }
+                R.id.menu_contact_diary_export_entries -> { true }
+                R.id.menu_contact_diary_edit_persons -> { true }
+                R.id.menu_contact_diary_edit_locations -> { true }
+                else -> contactDiaryOverviewFragment.onOptionsItemSelected(it)
+            }
+        }
+    }.show()
+}
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
new file mode 100644
index 000000000..dc5c1b920
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewNavigationEvents.kt
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 000000000..6040579a7
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
@@ -0,0 +1,96 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview
+
+import androidx.lifecycle.asLiveData
+import com.squareup.inject.assisted.AssistedInject
+import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter
+import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
+import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem
+import de.rki.coronawarnapp.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+import org.joda.time.LocalDate
+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) })
+
+    val listItems = combine(
+        dates,
+        contactDiaryRepository.locationVisits,
+        contactDiaryRepository.personEncounters
+    ) { dateList, locationVisitList, personEncounterList ->
+        createListItemList(dateList, locationVisitList, personEncounterList)
+    }.asLiveData()
+
+    private fun createListItemList(
+        dateList: List<LocalDate>,
+        locationVisitList: List<ContactDiaryLocationVisit>,
+        personEncounterList: List<ContactDiaryPersonEncounter>
+    ): List<ListItem> {
+        Timber.v(
+            "createListItemList(dateList=$dateList, " +
+                "locationVisitList=$locationVisitList, " +
+                "personEncounterList=$personEncounterList)"
+        )
+        return dateList
+            .map {
+                ListItem(it)
+                    .apply {
+                        data.addPersonEncountersForDate(personEncounterList, date)
+                        data.addLocationVisitsForDate(locationVisitList, date)
+                    }
+            }
+    }
+
+    private fun MutableList<ListItem.Data>.addPersonEncountersForDate(
+        personEncounterList: List<ContactDiaryPersonEncounter>,
+        date: LocalDate
+    ) {
+        this += personEncounterList
+            .filter { personEncounter -> personEncounter.date == date }
+            .map { personEncounter ->
+                ListItem.Data(
+                    R.drawable.ic_contact_diary_person,
+                    personEncounter.contactDiaryPerson.fullName
+                )
+            }
+    }
+
+    private fun MutableList<ListItem.Data>.addLocationVisitsForDate(
+        locationVisitList: List<ContactDiaryLocationVisit>,
+        date: LocalDate
+    ) {
+        this += locationVisitList
+            .filter { locationVisit -> locationVisit.date == date }
+            .map { locationVisit ->
+                ListItem.Data(
+                    R.drawable.ic_contact_diary_location,
+                    locationVisit.contactDiaryLocation.locationName
+                )
+            }
+    }
+
+    fun onBackButtonPress() {
+        routeToScreen.postValue(ContactDiaryOverviewNavigationEvents.NavigateToMainActivity)
+    }
+
+    fun onItemPress(listItem: ListItem) {
+        routeToScreen.postValue(ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment(listItem.date))
+    }
+
+    @AssistedInject.Factory
+    interface Factory : SimpleCWAViewModelFactory<ContactDiaryOverviewViewModel>
+
+    companion object {
+        const val DAY_COUNT = 14
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
new file mode 100644
index 000000000..bd54f8b70
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt
@@ -0,0 +1,63 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import de.rki.coronawarnapp.databinding.IncludeContactDiaryOverviewItemBinding
+import java.util.Locale
+
+class ContactDiaryOverviewAdapter(private val onItemSelectionListener: (ListItem) -> Unit) :
+    RecyclerView.Adapter<ContactDiaryOverviewAdapter.OverviewElementHolder>() {
+    private val elements: MutableList<ListItem> = mutableListOf()
+
+    fun setItems(elements: List<ListItem>) {
+        this.elements.clear()
+        this.elements += elements
+        notifyDataSetChanged()
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OverviewElementHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        return OverviewElementHolder(
+            IncludeContactDiaryOverviewItemBinding.inflate(
+                inflater,
+                parent,
+                false
+            )
+        )
+    }
+
+    override fun getItemCount() = elements.size
+
+    override fun onBindViewHolder(holder: OverviewElementHolder, position: Int) {
+        holder.bind(elements[position], onItemSelectionListener)
+    }
+
+    class OverviewElementHolder(private val viewDataBinding: IncludeContactDiaryOverviewItemBinding) :
+        RecyclerView.ViewHolder(viewDataBinding.root) {
+        private val nestedItemAdapter = ContactDiaryOverviewNestedAdapter()
+
+        init {
+            viewDataBinding.contactDiaryOverviewNestedRecyclerView.adapter = nestedItemAdapter
+        }
+
+        fun bind(
+            item: ListItem,
+            onElementSelectionListener: (ListItem) -> Unit
+        ) {
+            viewDataBinding.contactDiaryOverviewElementName.text =
+                item.date.toString("EEEE, dd.MM.yyyy", Locale.getDefault())
+
+            viewDataBinding.contactDiaryOverviewElementBody.setOnClickListener { onElementSelectionListener(item) }
+
+            if (item.data.isNotEmpty()) {
+                viewDataBinding.contactDiaryOverviewElementDivider.visibility = View.VISIBLE
+            } else {
+                viewDataBinding.contactDiaryOverviewElementDivider.visibility = View.INVISIBLE
+            }
+
+            nestedItemAdapter.setItems(item.data)
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
new file mode 100644
index 000000000..a1f06fe61
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
@@ -0,0 +1,37 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import de.rki.coronawarnapp.databinding.IncludeContactDiaryOverviewNestedItemBinding
+
+class ContactDiaryOverviewNestedAdapter :
+    RecyclerView.Adapter<ContactDiaryOverviewNestedAdapter.NestedItemViewHolder>() {
+
+    private val dataList: MutableList<ListItem.Data> = mutableListOf()
+
+    fun setItems(dataList: List<ListItem.Data>) {
+        this.dataList.clear()
+        this.dataList += dataList
+        notifyDataSetChanged()
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NestedItemViewHolder {
+        val inflater = LayoutInflater.from(parent.context)
+        return NestedItemViewHolder(IncludeContactDiaryOverviewNestedItemBinding.inflate(inflater, parent, false))
+    }
+
+    override fun onBindViewHolder(holder: NestedItemViewHolder, position: Int) {
+        holder.bind(dataList[position])
+    }
+
+    override fun getItemCount(): Int = dataList.size
+
+    class NestedItemViewHolder(private val viewBinding: IncludeContactDiaryOverviewNestedItemBinding) :
+        RecyclerView.ViewHolder(viewBinding.root) {
+        fun bind(data: ListItem.Data) {
+            viewBinding.contactDiaryOverviewElementImage.setImageResource(data.drawableId)
+            viewBinding.contactDiaryOverviewElementName.text = data.text
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
new file mode 100644
index 000000000..34e64afb2
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
@@ -0,0 +1,14 @@
+package de.rki.coronawarnapp.contactdiary.ui.overview.adapter
+
+import org.joda.time.LocalDate
+
+data class ListItem(
+    val date: LocalDate
+) {
+    val data: MutableList<Data> = mutableListOf()
+
+    data class Data(
+        val drawableId: Int,
+        val text: String
+    )
+}
diff --git a/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_location_item.xml b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_location_item.xml
new file mode 100644
index 000000000..b28a0bf0f
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_location_item.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="40dp"
+    android:height="40dp"
+    android:viewportWidth="40"
+    android:viewportHeight="40">
+  <path
+      android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
+      android:fillColor="#434445"/>
+  <path
+      android:pathData="M20,10C16.13,10 13,13.13 13,17C13,22.25 20,30 20,30C20,30 27,22.25 27,17C27,13.13 23.87,10 20,10ZM20,19.5C18.62,19.5 17.5,18.38 17.5,17C17.5,15.62 18.62,14.5 20,14.5C21.38,14.5 22.5,15.62 22.5,17C22.5,18.38 21.38,19.5 20,19.5Z"
+      android:fillColor="#83D2F2"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_person_item.xml b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_person_item.xml
new file mode 100644
index 000000000..6b5071820
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_person_item.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="40dp"
+    android:height="40dp"
+    android:viewportWidth="40"
+    android:viewportHeight="40">
+  <path
+      android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
+      android:fillColor="#434445"/>
+  <path
+      android:pathData="M20,20C22.21,20 24,18.21 24,16C24,13.79 22.21,12 20,12C17.79,12 16,13.79 16,16C16,18.21 17.79,20 20,20ZM20,22C17.33,22 12,23.34 12,26V28H28V26C28,23.34 22.67,22 20,22Z"
+      android:fillColor="#83D2F2"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_right_arrow.xml b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_right_arrow.xml
new file mode 100644
index 000000000..ba5299266
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable-night/ic_contact_diary_right_arrow.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="18dp"
+    android:height="14dp"
+    android:viewportWidth="18"
+    android:viewportHeight="14">
+  <path
+      android:pathData="M10.4356,0L9.0126,1.4851L13.3484,6.0099H0.0002V7.99H13.3484L9.0126,12.5149L10.4356,14L17.1431,7L10.4356,0Z"
+      android:fillColor="#A7A7A7"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_location_item.xml b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_location_item.xml
new file mode 100644
index 000000000..c92cf57c2
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_location_item.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="32"
+    android:viewportHeight="32">
+  <path
+      android:pathData="M16,16m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M16,6C12.13,6 9,9.13 9,13C9,18.25 16,26 16,26C16,26 23,18.25 23,13C23,9.13 19.87,6 16,6ZM16,15.5C14.62,15.5 13.5,14.38 13.5,13C13.5,11.62 14.62,10.5 16,10.5C17.38,10.5 18.5,11.62 18.5,13C18.5,14.38 17.38,15.5 16,15.5Z"
+      android:fillColor="#007FAD"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_person_item.xml b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_person_item.xml
new file mode 100644
index 000000000..79ca9aaf2
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_person_item.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="32"
+    android:viewportHeight="32">
+  <path
+      android:pathData="M16,16m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M16,16C18.21,16 20,14.21 20,12C20,9.79 18.21,8 16,8C13.79,8 12,9.79 12,12C12,14.21 13.79,16 16,16ZM16,18C13.33,18 8,19.34 8,22V24H24V22C24,19.34 18.67,18 16,18Z"
+      android:fillColor="#007FAD"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_right_arrow.xml b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_right_arrow.xml
new file mode 100644
index 000000000..a763aa41e
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_contact_diary_right_arrow.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="18dp"
+    android:height="14dp"
+    android:viewportWidth="18"
+    android:viewportHeight="14">
+  <path
+      android:pathData="M10.9572,0L9.463,1.4851L14.0156,6.0099H0V7.99H14.0156L9.463,12.5149L10.9572,14L18,7L10.9572,0Z"
+      android:fillColor="#17191A"
+      android:fillAlpha="0.6"
+      android:fillType="evenOdd"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml
new file mode 100644
index 000000000..1f84b76c9
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml
@@ -0,0 +1,85 @@
+<?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="match_parent">
+
+        <include
+            android:id="@+id/contact_diary_overview_header"
+            layout="@layout/include_contact_diary_overview_header"
+            android:layout_width="@dimen/match_constraint"
+            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/contact_diary_overview_header}" />
+
+
+        <TextView
+            android:id="@+id/onboarding_headline"
+            style="@style/headline6"
+            android:layout_marginTop="@dimen/spacing_tiny"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:accessibilityHeading="true"
+            android:focusable="true"
+            android:text="@string/contact_diary_overview_title"
+            app:layout_constraintEnd_toStartOf="@+id/guideline_end"
+            app:layout_constraintStart_toStartOf="@+id/guideline_start"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_overview_header"
+            tools:text="Kontakt-Tagebuch" />
+
+
+        <TextView
+            android:id="@+id/contact_diary_overview_subtitle"
+            style="@style/subtitleMedium"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/spacing_small"
+            android:focusable="true"
+            android:text="@string/contact_diary_overview_subtitle"
+            app:layout_constraintEnd_toEndOf="@id/guideline_end"
+            app:layout_constraintStart_toStartOf="@id/guideline_start"
+            app:layout_constraintTop_toBottomOf="@+id/onboarding_headline"
+            tools:text="Tragen Sie ein, mit wem Sie sich getroffen haben und wo Sie gewesen sind." />
+
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/contact_diary_overview_recyclerview"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="@dimen/match_constraint"
+            android:layout_marginHorizontal="@dimen/spacing_mega_tiny"
+            android:layout_marginTop="@dimen/spacing_small"
+            android:layout_marginBottom="@dimen/spacing_mega_tiny"
+            android:background="@color/colorSurface1"
+            android:scrollbars="vertical"
+            android:scrollbarSize="@dimen/spacing_mega_tiny"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="@id/guideline_end"
+            app:layout_constraintStart_toStartOf="@+id/guideline_start"
+            app:layout_constraintTop_toBottomOf="@+id/contact_diary_overview_subtitle"
+            app:layout_constraintVertical_bias="0.0"
+            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+            tools:listitem="@layout/include_contact_diary_overview_item" />
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline_start"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            app:layout_constraintGuide_begin="@dimen/guideline_start" />
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline_end"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            app:layout_constraintGuide_end="@dimen/guideline_end" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_header.xml b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_header.xml
new file mode 100644
index 000000000..b748919f8
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_header.xml
@@ -0,0 +1,78 @@
+<?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">
+
+    <data>
+
+        <variable
+            name="icon"
+            type="android.graphics.drawable.Drawable" />
+
+        <variable
+            name="title"
+            type="String" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/header_main"
+        android:id="@+id/contact_diary_header"
+        android:paddingTop="@dimen/spacing_tiny"
+        android:paddingBottom="@dimen/spacing_tiny">
+
+        <include
+            android:id="@+id/contact_diary_header_button_back"
+            layout="@layout/include_button_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:icon="@{icon}"
+            app:iconDescription="@{@string/accessibility_back}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="@id/guideline_back"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/contact_diary_header_title"
+            style="@style/headline6"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/guideline_body_title"
+            android:accessibilityHeading="true"
+            android:text="@{title}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@+id/contact_diary_header_options_menu"
+            app:layout_constraintStart_toStartOf="@id/guideline_start"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="@string/settings_title" />
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline_start"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            app:layout_constraintGuide_begin="@dimen/guideline_start" />
+
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            app:layout_constraintGuide_begin="@dimen/guideline_back" />
+
+        <include
+            android:id="@+id/contact_diary_header_options_menu"
+            layout="@layout/include_button_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="@dimen/spacing_small"
+            android:focusable="true"
+            app:icon="@{@drawable/ic_main_settings}"
+            app:iconDescription="@{@string/button_menu}"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_item.xml b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_item.xml
new file mode 100644
index 000000000..2c3efdd8b
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_item.xml
@@ -0,0 +1,59 @@
+<?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:id="@+id/contact_diary_overview_element_body"
+        style="@style/cardGrey"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/spacing_mega_tiny"
+        android:layout_marginBottom="@dimen/spacing_mega_tiny"
+        android:focusable="true">
+
+        <TextView
+            android:id="@+id/contact_diary_overview_element_name"
+            style="@style/contactDiaryListItem"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_small"
+            android:focusable="true"
+            android:text="Donnerstag, 01.12.2020"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_divider"
+            app:layout_constraintEnd_toStartOf="@+id/contact_diary_overview_element_right_arrow"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <ImageView
+            android:id="@+id/contact_diary_overview_element_right_arrow"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginVertical="@dimen/spacing_tiny"
+            android:layout_marginEnd="@dimen/spacing_small"
+            android:importantForAccessibility="no"
+            android:scaleType="centerInside"
+            android:src="@drawable/ic_contact_diary_right_arrow"
+            app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_divider"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <View
+            android:id="@+id/contact_diary_overview_element_divider"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/card_divider"
+            android:background="?android:attr/listDivider"
+            android:layout_marginTop="@dimen/contact_diary_list_item"
+            app:layout_constraintTop_toTopOf="parent"/>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/contact_diary_overview_nested_recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:nestedScrollingEnabled="false"
+            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_element_divider"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_nested_item.xml b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_nested_item.xml
new file mode 100644
index 000000000..3bdcce318
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/include_contact_diary_overview_nested_item.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:tools="http://schemas.android.com/tools"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/contact_diary_overview_element_nested_body"
+        style="@style/cardGrey"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:focusable="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:id="@+id/contact_diary_overview_element_image"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginVertical="@dimen/spacing_tiny"
+            android:layout_marginStart="@dimen/spacing_small"
+            android:importantForAccessibility="no"
+            android:scaleType="centerInside"
+            android:src="@drawable/ic_contact_diary_person_item"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/contact_diary_overview_element_name"
+            style="@style/headline5"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/spacing_small"
+            android:focusable="true"
+            android:text="Andrea Steinhauer"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/contact_diary_overview_element_image"
+            app:layout_constraintTop_toTopOf="parent" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/menu/menu_contact_diary_overview.xml b/Corona-Warn-App/src/main/res/menu/menu_contact_diary_overview.xml
new file mode 100644
index 000000000..25bde48e7
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/menu/menu_contact_diary_overview.xml
@@ -0,0 +1,15 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+    <item
+        android:id="@+id/menu_contact_diary_information"
+        android:title="@string/menu_contact_diary_information" />
+    <item
+        android:id="@+id/menu_contact_diary_export_entries"
+        android:title="@string/menu_contact_export_entries" />
+    <item
+        android:id="@+id/menu_contact_diary_edit_persons"
+        android:title="@string/menu_contact_diary_edit_persons" />
+    <item
+        android:id="@+id/menu_contact_diary_edit_locations"
+        android:title="@string/menu_contact_diary_edit_locations" />
+</menu>
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 ae8e26f5d..80999eff0 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
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <navigation 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"
     android:id="@+id/contact_diary_nav_graph"
     app:startDestination="@id/contactDiaryOnboardingFragment">
     <fragment
@@ -10,9 +11,17 @@
         <action
             android:id="@+id/action_contactDiaryOnboardingFragment_to_contactDiaryInformationPrivacyFragment"
             app:destination="@id/contactDiaryInformationPrivacyFragment" />
+        <action
+            android:id="@+id/action_contactDiaryOnboardingFragment_to_contactDiaryOverviewFragment"
+            app:destination="@id/contactDiaryOverviewFragment" />
     </fragment>
     <fragment
         android:id="@+id/contactDiaryInformationPrivacyFragment"
         android:name="de.rki.coronawarnapp.ui.information.InformationPrivacyFragment"
         android:label="InformationPrivacyFragment" />
+    <fragment
+        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" />
 </navigation>
diff --git a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
index d7d239cc4..1124c81da 100644
--- a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml
@@ -60,4 +60,19 @@
     <!-- XTXT: Title for legal information of the contact diary onboarding screen -->
     <string name="contact_diary_onboarding_privacy_information_title">Datenschutz und Datensicherheit</string>
 
+    <!-- XTXT: Menu information entry for contact diary overview screen -->
+    <string name="menu_contact_diary_information">Information</string>
+    <!-- XTXT: Menu export entry for contact diary overview screen -->
+    <string name="menu_contact_export_entries">Einträge exportieren</string>
+    <!-- XTXT: Menu edit persons entry for contact diary overview screen -->
+    <string name="menu_contact_diary_edit_persons">Personen bearbeiten</string>
+    <!-- XTXT: Menu edit locations entry for contact diary overview screen -->
+    <string name="menu_contact_diary_edit_locations">Orte bearbeiten</string>
+    <!-- XTXT: Title for contact diary overview screen -->
+    <string name="contact_diary_overview_title">Kontakt-Tagebuch</string>
+    <!-- XTXT: Subtitle for contact diary overview screen -->
+    <string name="contact_diary_overview_subtitle">Tragen Sie ein, mit wem Sie sich getroffen haben und wo Sie gewesen sind.</string>
+    <!-- XTXT: Header for contact diary overview screen -->
+    <string name="contact_diary_overview_header">Startseite</string>
+
 </resources>
\ No newline at end of file
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 1bd726524..31d261f1c 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
@@ -59,4 +59,19 @@
     <!-- XTXT: Title for legal information of the contact diary onboarding screen -->
     <string name="contact_diary_onboarding_privacy_information_title"/>
 
+    <!-- XTXT: Menu information entry for contact diary overview screen -->
+    <string name="menu_contact_diary_information"/>
+    <!-- XTXT: Menu export entry for contact diary overview screen -->
+    <string name="menu_contact_export_entries"/>
+    <!-- XTXT: Menu edit persons entry for contact diary overview screen -->
+    <string name="menu_contact_diary_edit_persons"/>
+    <!-- XTXT: Menu edit locations entry for contact diary overview screen -->
+    <string name="menu_contact_diary_edit_locations"/>
+    <!-- XTXT: Title for contact diary overview screen -->
+    <string name="contact_diary_overview_title"/>
+    <!-- XTXT: Subtitle for contact diary overview screen -->
+    <string name="contact_diary_overview_subtitle"/>
+    <!-- XTXT: Header for contact diary overview screen -->
+    <string name="contact_diary_overview_header"/>
+
 </resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values/dimens.xml b/Corona-Warn-App/src/main/res/values/dimens.xml
index 931435ba6..2b9975b56 100644
--- a/Corona-Warn-App/src/main/res/values/dimens.xml
+++ b/Corona-Warn-App/src/main/res/values/dimens.xml
@@ -136,4 +136,7 @@
     <dimen name="calendar_layout_stroke">2dp</dimen>
     <dimen name="calendar_day_size">40dp</dimen>
     <dimen name="calendar_day_spacing">4dp</dimen>
+
+    <!-- Contact Diary -->
+    <dimen name="contact_diary_list_item">65dp</dimen>
 </resources>
diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml
index fb0b8a3a4..f52ee4665 100644
--- a/Corona-Warn-App/src/main/res/values/styles.xml
+++ b/Corona-Warn-App/src/main/res/values/styles.xml
@@ -318,4 +318,13 @@
         <item name="android:fontFamily">sans-serif-black</item>
         <item name="android:letterSpacing">2</item>
     </style>
+
+    <!-- ####################################
+        Contact Diary
+    ###################################### -->
+    <style name="contactDiaryListItem" parent="@style/TextAppearance.MaterialComponents.Subtitle1">
+        <item name="android:textColor">@color/colorTextPrimary1</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
 </resources>
-- 
GitLab