diff --git a/Jenkinsfile b/Jenkinsfile
index 1b3c0a4ea09bd67f178de8e1efcfc97d57854f59..797871e69d0bf22a4e404ba46eff9ca3f8307a50 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -341,20 +341,26 @@ Void setAnsibleKubeConfig() {
 Void checkoutProvisioningRepo(String stage) {   
     withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
         dir(stage) {
-        sh 'git clone https://${USER}:${TOKEN}@git.ozg-sh.de/mgm/provisioning.git'
+            sh 'git clone https://${USER}:${TOKEN}@git.ozg-sh.de/mgm/provisioning.git'
 
-            // todo remove git checkout
-            //dir('provisioning') {
-            //    sh 'git checkout ozg-2552-jenkins-e2e'
-            //}
+            if (env.BRANCH_NAME == 'release') {
+                dir('provisioning') {
+                    sh 'git checkout release'
+                }
+            }
         }
     }
 }
 
 Void copyTestEnvironmentToDev(stage) {
     dir("${stage}/provisioning") {
-        def devEnvFile = "playbook/inventory/versions/dev.yml"
-        def testEnvFile = "playbook/inventory/versions/test.yml"
+        def devEnvFile = "inventories/group_vars/dev/versions"
+        def testEnvFile = "inventories/group_vars/test/versions"            
+
+        if (env.BRANCH_NAME == 'release') {
+            devEnvFile = "playbook/inventory/versions/dev.yml"
+            testEnvFile = "playbook/inventory/versions/test.yml"
+        }
 
         def devVersions = readYaml file: devEnvFile
         def testVersions = readYaml file: testEnvFile
@@ -368,7 +374,11 @@ Void copyTestEnvironmentToDev(stage) {
 
 Void editEnvironemntVersion(String stage, String imageTag, Boolean isEa) {
     dir("${stage}/provisioning") {
-        def editFile = "playbook/inventory/versions/dev.yml"
+        def editFile = "inventories/group_vars/dev/versions"
+        
+        if (env.BRANCH_NAME == 'release') {
+            editFile = "playbook/inventory/versions/dev.yml"
+        }
 
         def devVersions = readYaml file: editFile
 
@@ -380,8 +390,6 @@ Void editEnvironemntVersion(String stage, String imageTag, Boolean isEa) {
         devVersions.versions.goofy.image.tag = imageTag
 
         writeYaml file: editFile, data: devVersions, overwrite: true
-
-        sh "cat ${editFile}"
     }
 }
 
@@ -395,7 +403,12 @@ String getSpringProfile(Boolean isEa) {
 
 Void setupEaEnvironment(String stage) {
     dir("${stage}/provisioning") {
-        def editFile = "playbook/inventory/group_vars/all.yml"
+        def editFile = "inventories/group_vars/all/env"
+
+        if (env.BRANCH_NAME == 'release') {
+            editFile = "playbook/inventory/group_vars/all.yml"
+        }
+
         def groupVars = readYaml file: editFile
 
         groupVars.kop_einheitlicher_ansprechpartner = true
@@ -406,7 +419,12 @@ Void setupEaEnvironment(String stage) {
 
 Void setPlutoDatabasePassword(String stage) {
     dir("${stage}/provisioning") {
-        def editFile = "playbook/inventory/versions/dev.yml"
+        def editFile = "inventories/group_vars/dev/versions"
+        
+        if (env.BRANCH_NAME == 'release') {
+            editFile = "playbook/inventory/versions/dev.yml"
+        }
+
         def devVars = readYaml file: editFile
 
         devVars.values.pluto.database.password = "XnHhfznNWg65NNd"
@@ -427,7 +445,7 @@ Void rolloutKopStack(String bezeichner, String stage) {
                     "install_fs_adapter":false, \
                     "external_db_enabled":false}"""
 
-            sh "ansible-playbook playbook/rollout.yml --extra-vars '${ansibleVars}'"
+            sh "ansible-playbook playbooks/rollout.yml --extra-vars '${ansibleVars}'"
         }
     }
 }
@@ -446,7 +464,7 @@ Void addKeycloakGroups(String bezeichner, String stage) {
             }"""
 
             dir("${stage}/provisioning") {
-                sh "ansible-playbook playbook/add-keycloak-group.yml --extra-vars '${ansibleVars}'"
+                sh "ansible-playbook playbooks/add-keycloak-group.yml --extra-vars '${ansibleVars}'"
             }
     	}
     }
@@ -466,7 +484,7 @@ Void addKeycloakUser(String bezeichner, String stage) {
             }"""
 
             dir("${stage}/provisioning") {
-                sh "ansible-playbook playbook/add-keycloak-user.yml --extra-vars '${ansibleVars}'"
+                sh "ansible-playbook playbooks/add-keycloak-user.yml --extra-vars '${ansibleVars}'"
             }
         }
     }
@@ -479,7 +497,7 @@ Void deleteKopStack(String bezeichner, String stage) {
                     "kop_env":"dev", \
                     "kop_bezeichner":${bezeichner}}"""
 
-            sh "ansible-playbook playbook/delete-commune.yml --extra-vars '${ansibleVars}'"
+            sh "ansible-playbook playbooks/delete-commune.yml --extra-vars '${ansibleVars}'"
         }
     }
 }
diff --git a/goofy-client/.gitignore b/goofy-client/.gitignore
index 92abdb41d7fa17686e58d3ccf2fcb843520c83e7..29e0a78dc708bcd148daaa6b8c960be1b03544e4 100644
--- a/goofy-client/.gitignore
+++ b/goofy-client/.gitignore
@@ -26,7 +26,7 @@ test-report.xml
 
 # IDE - VSCode
 .vscode/*
-!.vscode/settings.json
+!.vscode/user-settings.json
 !.vscode/tasks.json
 !.vscode/launch.json
 !.vscode/extensions.json
diff --git a/goofy-client/angular.json b/goofy-client/angular.json
index 15cbd85cda3cb44f19ed835425974b5093c59d1b..defe2a61c3ccbc8cc46373d4f05e3d9ba15c8fca 100644
--- a/goofy-client/angular.json
+++ b/goofy-client/angular.json
@@ -800,6 +800,58 @@
 			},
 			"tags": []
 		},
+		"user-settings": {
+			"projectType": "library",
+			"root": "libs/user-settings",
+			"sourceRoot": "libs/user-settings/src",
+			"prefix": "goofy-client",
+			"architect": {
+				"test": {
+					"builder": "@nrwl/jest:jest",
+					"outputs": ["coverage/libs/user-settings"],
+					"options": {
+						"jestConfig": "libs/user-settings/jest.config.ts",
+						"passWithNoTests": true
+					}
+				},
+				"lint": {
+					"builder": "@nrwl/linter:eslint",
+					"options": {
+						"lintFilePatterns": [
+							"libs/user-settings/**/*.ts",
+							"libs/user-settings/**/*.html"
+						]
+					}
+				}
+			},
+			"tags": []
+		},
+		"user-settings-shared": {
+			"projectType": "library",
+			"root": "libs/user-settings-shared",
+			"sourceRoot": "libs/user-settings-shared/src",
+			"prefix": "goofy-client",
+			"architect": {
+				"test": {
+					"builder": "@nrwl/jest:jest",
+					"outputs": ["coverage/libs/user-settings-shared"],
+					"options": {
+						"jestConfig": "libs/user-settings-shared/jest.config.ts",
+						"passWithNoTests": true
+					}
+				},
+				"lint": {
+					"builder": "@nrwl/linter:eslint",
+					"options": {
+						"lintFilePatterns": [
+							"libs/user-settings-shared/**/*.ts",
+							"libs/user-settings-shared/**/*.html"
+						]
+					}
+				}
+			},
+			"tags": []
+		},
 		"vorgang": {
 			"$schema": "../../node_modules/nx/schemas/project-schema.json",
 			"projectType": "library",
diff --git a/goofy-client/libs/api-root-shared/src/lib/api-root.linkrel.ts b/goofy-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
index 8000a325a35eb37f6e7a3df85aa1381ae2aae312..986aaff9c951d9dd86635790a61096a7a24b05ce 100644
--- a/goofy-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
+++ b/goofy-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
@@ -4,5 +4,6 @@ export enum ApiRootLinkRel {
 	SEARCH = 'search',
 	SEARCH_MY_VORGAENGE = 'searchMyVorgaenge',
 	SEARCH_USER_PROFILES = 'search-user-profiles',
-	DOWNLOAD_TOKEN = 'downloadToken'
+	DOWNLOAD_TOKEN = 'downloadToken',
+	CURRENT_USER = 'currentUser'
 }
\ No newline at end of file
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header-container.component.html b/goofy-client/libs/navigation/src/lib/header-container/header-container.component.html
index 6c154413f00bbf66382205fede99a5854ba3474d..b1849bcf80fc12db4abd88f5e7cf5135b8ec4776 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header-container.component.html
+++ b/goofy-client/libs/navigation/src/lib/header-container/header-container.component.html
@@ -1,7 +1,5 @@
 <goofy-client-header
-	[darkMode]="darkMode$ | async"
 	[navigationCollapse]="navigationCollapse$ | async"
 	(toggleMenuEvent)="toggleNavigation($event)"
-	(logoutEmitter)="logout()"
-	(darkModeEmitter)="changeColorMode($event)">
+	(logoutEmitter)="logout()">
 </goofy-client-header>
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header-container.component.ts b/goofy-client/libs/navigation/src/lib/header-container/header-container.component.ts
index 62ee403fd64eaa32008e16c64506ff62d84666c8..1ac12eadeda9850e6c1a9ac4f24b74114a2b91ac 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header-container.component.ts
+++ b/goofy-client/libs/navigation/src/lib/header-container/header-container.component.ts
@@ -1,8 +1,7 @@
-import { DOCUMENT } from '@angular/common';
-import { Component, Inject, Renderer2 } from '@angular/core';
-import { Observable } from 'rxjs';
-import { AppService, localStorageDark } from '@goofy-client/app-shared';
+import { Component } from '@angular/core';
+import { AppService } from '@goofy-client/app-shared';
 import { OAuthService } from 'angular-oauth2-oidc';
+import { Observable } from 'rxjs';
 
 @Component({
   selector: 'goofy-client-header-container',
@@ -12,40 +11,18 @@ import { OAuthService } from 'angular-oauth2-oidc';
 export class HeaderContainerComponent {
 
 	navigationCollapse$: Observable<boolean>;
-	darkMode$: Observable<boolean>;
 
 	constructor(
 		private appService: AppService,
-		private renderer: Renderer2,
 		private authService: OAuthService,
-		@Inject(DOCUMENT) private document: Document,
 	) {
 		this.navigationCollapse$ = this.appService.getNavigationCollapse();
-		this.darkMode$ = this.appService.getDarkMode();
-
-		this.subscribeToDarkMode();
-	}
-
- 	private subscribeToDarkMode(): void {
-		this.darkMode$.subscribe(darkMode => darkMode ? this.addClass(localStorageDark) : this.removeClass(localStorageDark));
-	}
-
-	private addClass(styleClass: string): void {
-		this.renderer.addClass(this.document.body, styleClass);
-	}
-
-	private removeClass(styleClass: string): void {
-		this.renderer.removeClass(this.document.body, styleClass);
 	}
 
 	toggleNavigation(isToggle: boolean): void {
 		this.appService.setNavigationCollapse(isToggle);
 	}
 
-	changeColorMode(darkMode: boolean): void {
-		this.appService.setDarkMode(darkMode);
-	}
-
 	logout(): void {
 		this.authService.logOut();
 	}
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html
index 134e2eb48e0fc15ec4a0acefda7fcb6d1a787974..c78c10edbecd236a8aade17986afee2b91bb5f00 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html
+++ b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.html
@@ -15,7 +15,7 @@
 
 	<div class="right">
 
-		<goofy-client-settings [darkMode]="darkMode" (darkModeEmitter)="darkModeEmitter.emit($event)"></goofy-client-settings>
+		<goofy-client-user-settings-container></goofy-client-user-settings-container>
 
 		<!-- TODO: User Profile in eigene Componente auslagern -->
 		<button mat-icon-button [matMenuTriggerFor]="accountMenu" class="big-button" aria-label="Benutzerkonto" data-test-id="user-icon-button"
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.spec.ts b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.spec.ts
index 91c6f922af079ff0e8ffbaf4c983bf507f95096f..95d1a9f99f545a4a2e68d68ddfddb3285d697027 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.spec.ts
+++ b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.spec.ts
@@ -5,7 +5,6 @@ import { UserIconComponent } from '@goofy-client/user-profile';
 import { VorgangSearchContainerComponent } from '@goofy-client/vorgang-shared-ui';
 import { MockComponent } from 'ng-mocks';
 import { HeaderComponent } from './header.component';
-import { SettingsComponent } from './settings/settings.component';
 
 describe('HeaderComponent', () => {
 	let component: HeaderComponent;
@@ -19,7 +18,6 @@ describe('HeaderComponent', () => {
 			],
 			declarations: [
 				HeaderComponent,
-				MockComponent(SettingsComponent),
 				MockComponent(VorgangSearchContainerComponent),
 				MockComponent(UserIconComponent)
 			]
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.ts b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.ts
index afe00d897777519bc30950381a274dbef22f842c..a36d7cf9fcac0bb9118819fe7a20f149ee1b72db 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header/header.component.ts
+++ b/goofy-client/libs/navigation/src/lib/header-container/header/header.component.ts
@@ -7,10 +7,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
 })
 export class HeaderComponent {
 
-	@Input() darkMode: boolean;
 	@Input() navigationCollapse: boolean;
 
 	@Output() public toggleMenuEvent: EventEmitter<boolean> = new EventEmitter<boolean>()
-	@Output() public darkModeEmitter: EventEmitter<boolean> = new EventEmitter<boolean>()
 	@Output() public logoutEmitter: EventEmitter<void> = new EventEmitter<void>()
 }
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.html b/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.html
deleted file mode 100644
index 328924bb484a216e2585348bd05c347a55c1d031..0000000000000000000000000000000000000000
--- a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<goofy-client-icon-button-with-spinner
-		icon="settings"
-		toolTip="Einstellungen"
-		[matMenuTriggerFor]="settingsMenu"
-		(menuOpened)="toggle.focus()">
-</goofy-client-icon-button-with-spinner>
-
-<mat-menu #settingsMenu="matMenu" >
-	<div class="menu-container"
-		(click)="$event.stopPropagation()">
-
-		<mat-slide-toggle color="primary" #toggle
-			[checked]="darkMode"
-			(change)="darkModeEmitter.emit($event.checked)">Dark Mode
-		</mat-slide-toggle>
-	</div>
-</mat-menu>
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.spec.ts b/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.spec.ts
deleted file mode 100644
index 1f02826aa49ea3fcd1ad2dcd2cc715a9dd4dc826..0000000000000000000000000000000000000000
--- a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.spec.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { UiModule } from '@goofy-client/ui';
-import { SettingsComponent } from './settings.component';
-
-describe('SettingsComponent', () => {
-	let component: SettingsComponent;
-	let fixture: ComponentFixture<SettingsComponent>;
-
-	beforeEach(async () => {
-		await TestBed.configureTestingModule({
-			imports: [
-				UiModule
-			],
-			declarations: [SettingsComponent]
-		})
-			.compileComponents();
-	});
-
-	beforeEach(() => {
-		fixture = TestBed.createComponent(SettingsComponent);
-		component = fixture.componentInstance;
-		fixture.detectChanges();
-	});
-
-	it('should create', () => {
-		expect(component).toBeTruthy();
-	});
-});
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.ts b/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.ts
deleted file mode 100644
index 7bc806c429c5aff658956b1fd6947f143a2384c5..0000000000000000000000000000000000000000
--- a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-
-@Component({
-	selector: 'goofy-client-settings',
-	templateUrl: './settings.component.html',
-	styleUrls: ['./settings.component.scss']
-})
-export class SettingsComponent {
-
-	@Input() darkMode: boolean;
-
-	@Output() public darkModeEmitter: EventEmitter<boolean> = new EventEmitter();
-}
\ No newline at end of file
diff --git a/goofy-client/libs/navigation/src/lib/navigation.module.ts b/goofy-client/libs/navigation/src/lib/navigation.module.ts
index 78ac06b69038c5a945f9eeb24bea8af80aef88d0..6c8d699901ecfb1d27ce898e9e2031d8b6be0c77 100644
--- a/goofy-client/libs/navigation/src/lib/navigation.module.ts
+++ b/goofy-client/libs/navigation/src/lib/navigation.module.ts
@@ -3,11 +3,11 @@ import { NgModule } from '@angular/core';
 import { RouterModule } from '@angular/router';
 import { UiModule } from '@goofy-client/ui';
 import { UserProfileModule } from '@goofy-client/user-profile';
+import { UserSettingsModule } from '@goofy-client/user-settings';
 import { VorgangSharedUiModule } from '@goofy-client/vorgang-shared-ui';
 import { BuildInfoComponent } from './build-info/build-info.component';
 import { HeaderContainerComponent } from './header-container/header-container.component';
 import { HeaderComponent } from './header-container/header/header.component';
-import { SettingsComponent } from './header-container/header/settings/settings.component';
 import { NavigationContainerComponent } from './navigation-container/navigation-container.component';
 import { AllVorgaengeNavigationItemComponent } from './navigation/all-vorgaenge-navigation-item/all-vorgaenge-navigation-item.component';
 import { MyVorgaengeNavigationItemComponent } from './navigation/my-vorgaenge-navigation-item/my-vorgaenge-navigation-item.component';
@@ -18,23 +18,23 @@ import { NavigationComponent } from './navigation/navigation.component';
 		BuildInfoComponent,
 		HeaderComponent,
 		NavigationComponent,
-		SettingsComponent,
 		HeaderContainerComponent,
 		AllVorgaengeNavigationItemComponent,
 		MyVorgaengeNavigationItemComponent,
-		NavigationContainerComponent
+		NavigationContainerComponent,
 	],
 	imports: [
 		CommonModule,
 		UiModule,
 		RouterModule,
 		VorgangSharedUiModule,
-		UserProfileModule
+		UserProfileModule,
+		UserSettingsModule,
 	],
 	exports: [
 		BuildInfoComponent,
 		NavigationContainerComponent,
-		HeaderContainerComponent
-	]
+		HeaderContainerComponent,
+	],
 })
-export class NavigationModule { }
+export class NavigationModule {}
diff --git a/goofy-client/libs/postfach/src/lib/postfach.module.ts b/goofy-client/libs/postfach/src/lib/postfach.module.ts
index 73e5115ee1bee6a0e9e982106aca8e73328180bb..51873ed48f38cdce082bd9ff7acd6df11c9c46e0 100644
--- a/goofy-client/libs/postfach/src/lib/postfach.module.ts
+++ b/goofy-client/libs/postfach/src/lib/postfach.module.ts
@@ -27,7 +27,7 @@ const routes: Routes = [
 	{
 		path: 'postfach',
 		component: PostfachPageContainerComponent,
-		title: 'Postfach zum Vorgang | Alfa'
+		title: 'Nachrichten zum Vorgang | Alfa'
 	}
 ];
 
diff --git a/goofy-client/libs/user-profile-shared/src/lib/user-profile.linkrel.ts b/goofy-client/libs/user-profile-shared/src/lib/user-profile.linkrel.ts
index 4104372b1212e0fdc02175fe2ed998e8515afd02..73fa1ade46d27383297e8da2b2c3f1a8144cd841 100644
--- a/goofy-client/libs/user-profile-shared/src/lib/user-profile.linkrel.ts
+++ b/goofy-client/libs/user-profile-shared/src/lib/user-profile.linkrel.ts
@@ -1,3 +1,7 @@
 export enum UserProfileListLinkRel {
 	USER_PROFILE_LIST = 'userProfileList'
+}
+
+export enum UserProfileLinkRel {
+	SETTINGS = 'settings'
 }
\ No newline at end of file
diff --git a/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.spec.ts b/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.spec.ts
index 8bda09c735375376e7164654c0cbf99d35c01276..90347798b1f7fed959be287e47a0f5b8d625c96b 100644
--- a/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.spec.ts
+++ b/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.spec.ts
@@ -6,8 +6,8 @@ import { ResourceFactory } from '@ngxp/rest';
 import { cold, hot } from 'jest-marbles';
 import { createApiRootResource } from 'libs/api-root-shared/test/api-root';
 import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang';
-import { createUserProfileResource } from '../../test/user-profile';
-import { UserProfileResource } from './user-profile.model';
+import { createUserProfileListResource, createUserProfileResource } from '../../test/user-profile';
+import { UserProfileListResource, UserProfileResource } from './user-profile.model';
 import { UserProfileRepository } from './user-profile.repository';
 
 describe('User profile repository', () => {
@@ -62,6 +62,11 @@ describe('User profile repository', () => {
 	describe('search', () => {
 
 		const searchBy: string = 'SearchMe';
+		const userProfileListResource: UserProfileListResource = createUserProfileListResource();
+
+		beforeEach(() => {
+			resourceWrapper.get.mockReturnValue(cold('a', { a: userProfileListResource }));
+		})
 
 		it('should call resource factory', () => {
 			repository.search(apiRoot, searchBy);
@@ -76,5 +81,34 @@ describe('User profile repository', () => {
 
 			expect(repository.buildSearchByUrl).toHaveBeenCalledWith(apiRoot, searchBy);
 		})
+
+		it('should return result', () => {
+			const result = repository.search(apiRoot, searchBy);
+
+			expect(result).not.toBeNull();
+			expect(result).toBeObservable(hot('a', { a: userProfileListResource }));
+		})
+	})
+
+	describe('getCurrentUser', () => {
+
+		it('should call resource Factory', () => {
+			repository.getCurrentUser(apiRoot);
+
+			expect(resourceFactory.from).toHaveBeenCalledWith(apiRoot);
+		})
+
+		it('should call get', () => {
+			repository.getCurrentUser(apiRoot);
+
+			expect(resourceWrapper.get).toHaveBeenCalledWith(ApiRootLinkRel.CURRENT_USER);
+		})
+
+		it('should return result', () => {
+			const result = repository.getCurrentUser(apiRoot);
+
+			expect(result).not.toBeNull();
+			expect(result).toBeObservable(hot('a', { a: userProfile }));
+		})
 	})
 })
\ No newline at end of file
diff --git a/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.ts b/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.ts
index fc4b664f89c47233192df93ebbf8ed721ce71b12..f2c00f2de50c0bddc7d1d1b824895300cd406bb5 100644
--- a/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.ts
+++ b/goofy-client/libs/user-profile-shared/src/lib/user-profile.repository.ts
@@ -17,6 +17,10 @@ export class UserProfileRepository {
 		return this.resourceFactory.from(resource).get(linkRel);
 	}
 
+	public getCurrentUser(apiRootResource: ApiRootResource): Observable<UserProfileResource> {
+		return this.resourceFactory.from(apiRootResource).get(ApiRootLinkRel.CURRENT_USER);
+	}
+
 	@SkipInterceptor()
 	public search(apiRoot: ApiRootResource, searchBy: string): Observable<UserProfileListResource> {
 		return this.resourceFactory.fromId(this.buildSearchByUrl(apiRoot, searchBy)).get();
diff --git a/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.spec.ts b/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.spec.ts
index 907e09c4255f11136747e727c7cdcd7cfa9ad89b..ea98a04cdb6d5ab2e475ce288d58d92b64717a17 100644
--- a/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.spec.ts
+++ b/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.spec.ts
@@ -40,6 +40,29 @@ describe('UserProfileService', () => {
 		expect(service).toBeTruthy();
 	})
 
+	describe('getCurrentUser', () => {
+
+		const apiRootResource = createApiRootResource(["currentUser"]);
+
+		it('should call repository', (done) => {
+			apiRootFacade.getApiRoot.mockReturnValue(of(createStateResource(apiRootResource)));
+
+			service.getCurrentUser().subscribe(() => {
+				expect(repository.getCurrentUser).toHaveBeenCalledWith(apiRootResource);
+				done();
+			})
+		})
+
+		it('should call apiRoot facade', (done) => {
+			apiRootFacade.getApiRoot.mockReturnValue(of(createStateResource(apiRootResource)));
+
+			service.getCurrentUser().subscribe(() => {
+				expect(apiRootFacade.getApiRoot).toHaveBeenCalled();
+				done();
+			})
+		})
+	})
+
 	describe('load user profile', () => {
 
 		const linkRel: string = VorgangHeaderLinkRel.ASSIGNED_TO;
@@ -94,8 +117,6 @@ describe('UserProfileService', () => {
 
 	describe('createStateResourceForUpdate', () => {
 
-		const linkRel: string = VorgangHeaderLinkRel.ASSIGNED_TO;
-
 		beforeEach(() => {
 			service.updateUserProfile = jest.fn();
 		})
diff --git a/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.ts b/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.ts
index 833069c79479588526257058ed0e80cf78c8fc25..e82eacaaabf0849ec1ee239dbaf8a7d717cabc17 100644
--- a/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.ts
+++ b/goofy-client/libs/user-profile-shared/src/lib/user-profile.service.ts
@@ -18,6 +18,7 @@ export class UserProfileService {
 	private userProfiles = {};
 	private userProfileSearchList: BehaviorSubject<StateResource<UserProfileListResource>> = new BehaviorSubject(createEmptyStateResource<UserProfileListResource>());
 	private userProfileSearchVisibility: BehaviorSubject<boolean> = new BehaviorSubject(false);
+	private currentUser: BehaviorSubject<StateResource<UserProfileResource>> = new BehaviorSubject(createEmptyStateResource<UserProfileResource>());
 
 	private navigationSubscription: Subscription;
 
@@ -66,6 +67,24 @@ export class UserProfileService {
 		return this.userProfiles[uri].asObservable();
 	}
 
+	public getCurrentUser(): Observable<StateResource<UserProfileResource>> {
+		doIfLoadingRequired(this.currentUser.getValue(), () => {
+			this.loadCurrentUser().subscribe(currentUser => {
+				this.currentUser.next(createStateResource(currentUser));
+			});
+		});
+
+		return this.currentUser;
+	}
+
+	private loadCurrentUser(): Observable<UserProfileResource> {
+		return this.apiRootFacade.getApiRoot().pipe(
+			filter(stateResource => stateResource.loaded),
+			mergeMap(stateResource => this.repository.getCurrentUser(stateResource.resource)),
+			first()
+		)
+	}
+
 	createIfNotExist(uri: ResourceUri): void {
 		if (isNil(this.userProfiles[uri])) this.userProfiles[uri] = new BehaviorSubject(createEmptyStateResource<UserProfileResource>());
 	}
diff --git a/goofy-client/libs/user-settings-shared/.eslintrc.json b/goofy-client/libs/user-settings-shared/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..28f19b630511beab4ad3ff61ffce5a45f7430728
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/.eslintrc.json
@@ -0,0 +1,36 @@
+{
+	"extends": ["../../.eslintrc.json"],
+	"ignorePatterns": ["!**/*"],
+	"overrides": [
+		{
+			"files": ["*.ts"],
+			"extends": [
+				"plugin:@nrwl/nx/angular",
+				"plugin:@angular-eslint/template/process-inline-templates"
+			],
+			"rules": {
+				"@angular-eslint/directive-selector": [
+					"error",
+					{
+						"type": "attribute",
+						"prefix": "goofyClient",
+						"style": "camelCase"
+					}
+				],
+				"@angular-eslint/component-selector": [
+					"error",
+					{
+						"type": "element",
+						"prefix": "goofy-client",
+						"style": "kebab-case"
+					}
+				]
+			}
+		},
+		{
+			"files": ["*.html"],
+			"extends": ["plugin:@nrwl/nx/angular-template"],
+			"rules": {}
+		}
+	]
+}
diff --git a/goofy-client/libs/user-settings-shared/README.md b/goofy-client/libs/user-settings-shared/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ecf49402144e0af5e146cd92f6cdfb84d8e3b27d
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/README.md
@@ -0,0 +1,7 @@
+# user-settings-shared
+
+This library was generated with [Nx](https://nx.dev).
+
+## Running unit tests
+
+Run `nx test user-settings-shared` to execute the unit tests.
diff --git a/goofy-client/libs/user-settings-shared/jest.config.ts b/goofy-client/libs/user-settings-shared/jest.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..30536d499921584f63ac37a1ff20e268104c0727
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/jest.config.ts
@@ -0,0 +1,22 @@
+/* eslint-disable */
+export default {
+	displayName: 'user-settings-shared',
+	preset: '../../jest.preset.js',
+	setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
+	globals: {
+		'ts-jest': {
+			tsconfig: '<rootDir>/tsconfig.spec.json',
+			stringifyContentPathRegex: '\\.(html|svg)$',
+		},
+	},
+	coverageDirectory: '../../coverage/libs/user-settings-shared',
+	transform: {
+		'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
+	},
+	transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
+	snapshotSerializers: [
+		'jest-preset-angular/build/serializers/no-ng-attributes',
+		'jest-preset-angular/build/serializers/ng-snapshot',
+		'jest-preset-angular/build/serializers/html-comment',
+	],
+};
diff --git a/goofy-client/libs/user-settings-shared/src/index.ts b/goofy-client/libs/user-settings-shared/src/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..235538f5c463f0d4fb95039df9d22d2544b60eb4
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/index.ts
@@ -0,0 +1,10 @@
+export * from './lib/+state/user-settings.actions';
+export * from './lib/+state/user-settings.facade';
+export * from './lib/+state/user-settings.models';
+export * from './lib/+state/user-settings.reducer';
+export * from './lib/+state/user-settings.selectors';
+export * from './lib/user-settings-shared.module';
+export * from './lib/user-settings.linkrel';
+export * from './lib/user-settings.model';
+export * from './lib/user-settings.service';
+
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.actions.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..012f5a12ecd628fbb071b37ffe31d3c4a849315f
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.actions.ts
@@ -0,0 +1,55 @@
+import { ApiError } from '@goofy-client/tech-shared';
+import { UserProfileResource } from '@goofy-client/user-profile-shared';
+import { ActionCreator, createAction, props } from '@ngrx/store';
+import { TypedAction } from '@ngrx/store/src/models';
+import { UserSettings, UserSettingsResource } from '../user-settings.model';
+
+//TODO centralize ActionCreate
+export interface UserSettingsActionCreator<T> extends ActionCreator<string, (props: T) => T & TypedAction<string>> { }
+export interface TypedActionCreator extends ActionCreator<string, () => TypedAction<string>> { }
+
+export interface UserProfileAction {
+	currentUser: UserProfileResource
+}
+
+export interface LoadedUserSettingsAction {
+	userSettings: UserSettingsResource
+}
+
+export interface SetUserSettingsAction {
+	userSettings: UserSettings
+}
+
+export interface ApiErrorAction {
+	apiError: ApiError
+}
+
+export const loadUserSettings: UserSettingsActionCreator<UserProfileAction> = createAction(
+	'[UserSettings] Load UserSettings',
+	props<{ currentUser: UserProfileResource }>()
+);
+
+export const loadUserSettingsSuccess: UserSettingsActionCreator<LoadedUserSettingsAction> = createAction(
+	'[UserSettings/API] Load UserSettings Success',
+	props<{ userSettings: UserSettingsResource }>()
+);
+
+export const loadUserSettingsFailure: UserSettingsActionCreator<ApiErrorAction> = createAction(
+	'[UserSettings/API] Load UserSettings Failure',
+	props<ApiErrorAction>()
+);
+
+export const setUserSettings: UserSettingsActionCreator<SetUserSettingsAction> = createAction(
+	'[UserSettings] Set UserSettings',
+	props<{ userSettings: UserSettings }>()
+);
+
+export const setUserSettingsSuccess: UserSettingsActionCreator<LoadedUserSettingsAction> = createAction(
+	'[UserSettings/API] Set UserSettings Success',
+	props<{ userSettings: UserSettingsResource }>()
+);
+
+export const setUserSettingsFailure: UserSettingsActionCreator<ApiErrorAction> = createAction(
+	'[UserSettings/API] Set UserSettings Failure',
+	props<ApiErrorAction>()
+);
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..610edb8a004d9e7e3f0aa780a9bc6772403edcd9
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.spec.ts
@@ -0,0 +1,123 @@
+import { TestBed } from '@angular/core/testing';
+import { ApiError, createStateResource } from '@goofy-client/tech-shared';
+import { Mock, mock } from '@goofy-client/test-utils';
+import { UserProfileResource } from '@goofy-client/user-profile-shared';
+import { provideMockActions } from '@ngrx/effects/testing';
+import { Action } from '@ngrx/store';
+import { provideMockStore } from '@ngrx/store/testing';
+import { NxModule } from '@nrwl/angular';
+import { cold, hot } from 'jest-marbles';
+import { createApiError } from 'libs/tech-shared/test/error';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { Observable, of } from 'rxjs';
+import { UserSettings, UserSettingsResource } from '../user-settings.model';
+import { UserSettingsRepository } from '../user-settings.repository';
+import * as UserSettingsActions from './user-settings.actions';
+import { UserSettingsEffects } from './user-settings.effects';
+import { UserSettingsFacade } from './user-settings.facade';
+
+describe('UserSettingsEffects', () => {
+	let actions: Observable<Action>;
+	let effects: UserSettingsEffects;
+
+	const userSettingsFacade: Mock<UserSettingsFacade> = mock(UserSettingsFacade);
+	const userSettingsRepository: Mock<UserSettingsRepository> = mock(UserSettingsRepository);
+
+	beforeEach(() => {
+		TestBed.configureTestingModule({
+			imports: [NxModule.forRoot()],
+			providers: [
+				UserSettingsEffects,
+				provideMockActions(() => actions),
+				provideMockStore(),
+				{
+					provide: UserSettingsRepository,
+					useValue: userSettingsRepository
+				},
+				{
+					provide: UserSettingsFacade,
+					useValue: userSettingsFacade
+				}
+			],
+		});
+
+		effects = TestBed.inject(UserSettingsEffects);
+	});
+
+	describe('loadUserSettings', () => {
+		const currentUser: UserProfileResource = createUserProfileResource();
+		const action = UserSettingsActions.loadUserSettings({ currentUser });
+		const userSettings: UserSettingsResource = createUserSettingsResource();
+
+		it('should call repository', () => {
+			actions = of(action);
+
+			effects.loadUserSettings$.subscribe();
+
+			expect(userSettingsRepository.getUserSettings).toHaveBeenCalledWith(currentUser);
+		})
+
+		it('should dispatch success action', () => {
+			userSettingsRepository.getUserSettings.mockReturnValue(of(userSettings));
+
+			actions = hot('-a', { a: action });
+
+			const expected = cold('-b', { b: UserSettingsActions.loadUserSettingsSuccess({ userSettings }) });
+			expect(effects.loadUserSettings$).toBeObservable(expected);
+		})
+
+		it('should dispatch error action', () => {
+			const apiError: ApiError = createApiError()
+			const error = { error: { error: apiError } };
+			const errorResponse = cold('-#', {}, error);
+			userSettingsRepository.getUserSettings = jest.fn(() => errorResponse);
+
+			const expected = cold('--b', { b: UserSettingsActions.loadUserSettingsFailure({ apiError }) });
+			actions = hot('-a', { a: action });
+
+			expect(effects.loadUserSettings$).toBeObservable(expected);
+		})
+	})
+
+	describe('set user settings', () => {
+
+		const userSettingsResource: UserSettingsResource = createUserSettingsResource();
+		const userSettings: UserSettings = createUserSettings();
+		const action = UserSettingsActions.setUserSettings({ userSettings });
+
+		beforeEach(() => {
+			userSettingsFacade.getUserSettings.mockReturnValue(of(createStateResource(userSettingsResource)));
+			userSettingsRepository.setUserSettings.mockReturnValue(of(userSettingsResource));
+		})
+
+		it('should call repository', () => {
+			actions = of(action);
+
+			effects.setUserSettings$.subscribe();
+
+			expect(userSettingsRepository.setUserSettings).toHaveBeenCalledWith(userSettingsResource, userSettings);
+		})
+
+		it('should dispatch success action', () => {
+			userSettingsRepository.setUserSettings.mockReturnValue(of(userSettingsResource));
+
+			actions = hot('-a-|', { a: action });
+
+			const expected = cold('-a-|', { a: UserSettingsActions.setUserSettingsSuccess({ userSettings: userSettingsResource }) });
+			expect(effects.setUserSettings$).toBeObservable(expected);
+		})
+
+		it('should dispatch error action', () => {
+			const apiError: ApiError = createApiError()
+			const error = { error: { error: apiError } };
+			const errorResponse = cold('-#', {}, error);
+			userSettingsRepository.setUserSettings = jest.fn(() => errorResponse);
+
+			const expected = cold('--b', { b: UserSettingsActions.setUserSettingsFailure({ apiError }) });
+			actions = hot('-a', { a: action });
+
+			expect(effects.setUserSettings$).toBeObservable(expected);
+		})
+	})
+});
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0ecf7fad1b20fa49b197011e8c6aba69d220597e
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.effects.ts
@@ -0,0 +1,39 @@
+import { Injectable } from '@angular/core';
+import { getApiErrorFromHttpErrorResponse } from '@goofy-client/tech-shared';
+import { Actions, concatLatestFrom, createEffect, ofType } from '@ngrx/effects';
+import { of } from 'rxjs';
+import { catchError, map, switchMap } from 'rxjs/operators';
+import { UserSettingsRepository } from '../user-settings.repository';
+import * as UserSettingsActions from './user-settings.actions';
+import { UserSettingsFacade } from './user-settings.facade';
+
+@Injectable()
+export class UserSettingsEffects {
+
+	constructor(
+		private readonly actions$: Actions,
+		private readonly repository: UserSettingsRepository,
+		private readonly userSettingsFacade: UserSettingsFacade
+	) { }
+
+	loadUserSettings$ = createEffect(() =>
+		this.actions$.pipe(
+			ofType(UserSettingsActions.loadUserSettings),
+			switchMap((action) => this.repository.getUserSettings(action.currentUser).pipe(
+				map(userSettings => UserSettingsActions.loadUserSettingsSuccess({ userSettings })),
+				catchError(error => of(UserSettingsActions.loadUserSettingsFailure({ apiError: getApiErrorFromHttpErrorResponse(error) })))
+			))
+		)
+	)
+
+	setUserSettings$ = createEffect(() =>
+		this.actions$.pipe(
+			ofType(UserSettingsActions.setUserSettings),
+			concatLatestFrom(() => this.userSettingsFacade.getUserSettings()),
+			switchMap(([action, userSettingsResource]) => this.repository.setUserSettings(userSettingsResource.resource, action.userSettings).pipe(
+				map(userSettings => UserSettingsActions.setUserSettingsSuccess({ userSettings })),
+				catchError(error => of(UserSettingsActions.setUserSettingsFailure({ apiError: getApiErrorFromHttpErrorResponse(error) })))
+			))
+		)
+	)
+}
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6430fd793bebf2dbe96d971fe307920e2f793121
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.spec.ts
@@ -0,0 +1,57 @@
+import { createStateResource, StateResource } from '@goofy-client/tech-shared';
+import { Mock, mock, useFromMock } from '@goofy-client/test-utils';
+import { UserProfileResource } from '@goofy-client/user-profile-shared';
+import { Store } from '@ngrx/store';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { Subject } from 'rxjs';
+import { UserSettings, UserSettingsResource } from '../user-settings.model';
+import * as UserSettingsActions from './user-settings.actions';
+import { UserSettingsFacade } from './user-settings.facade';
+
+
+describe('UserSettingsFacade', () => {
+	const store: Mock<Store> = mock(Store);
+	let facade: UserSettingsFacade;
+	let userSettingsSubj: Subject<StateResource<UserSettingsResource>>;
+
+	beforeEach(() => {
+		userSettingsSubj = new Subject();
+		store.select.mockReturnValue(userSettingsSubj);
+
+		facade = new UserSettingsFacade(useFromMock(store));
+	});
+
+	describe('loadUserSettings', () => {
+		it('should dispatch "loadUserSettings"', () => {
+			const currentUser: UserProfileResource = createUserProfileResource();
+
+			facade.loadUserSettings(currentUser);
+
+			expect(store.dispatch).toHaveBeenCalledWith(UserSettingsActions.loadUserSettings({ currentUser }))
+		})
+	})
+
+	describe('getUserSettings', () => {
+		it('should return selected value', (done) => {
+			const expected: StateResource<UserSettingsResource> = createStateResource(createUserSettingsResource());
+
+			facade.getUserSettings().subscribe(userSettings => {
+				expect(userSettings).toBe(expected);
+				done();
+			});
+
+			userSettingsSubj.next(expected);
+		})
+	})
+
+	describe('setUserSettings', () => {
+		it('should dispatch "setUserSettings"', () => {
+			const userSettings: UserSettings = createUserSettings();
+
+			facade.setUserSettings(userSettings);
+
+			expect(store.dispatch).toHaveBeenCalledWith(UserSettingsActions.setUserSettings({ userSettings }));
+		})
+	})
+});
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fd419459644778fcc0186b3d1ea37600ec40f17
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.facade.ts
@@ -0,0 +1,26 @@
+import { Injectable } from '@angular/core';
+import { StateResource } from '@goofy-client/tech-shared';
+import { UserProfileResource } from '@goofy-client/user-profile-shared';
+import { Store } from '@ngrx/store';
+import { Observable } from 'rxjs';
+import { UserSettings, UserSettingsResource } from '../user-settings.model';
+import * as UserSettingsAction from './user-settings.actions';
+import * as UserSettingsSelectors from './user-settings.selectors';
+
+@Injectable()
+export class UserSettingsFacade {
+
+	constructor(private readonly store: Store) { }
+
+	public loadUserSettings(currentUser: UserProfileResource): void {
+		this.store.dispatch(UserSettingsAction.loadUserSettings({ currentUser }));
+	}
+
+	public getUserSettings(): Observable<StateResource<UserSettingsResource>> {
+		return this.store.select(UserSettingsSelectors.userSettings)
+	}
+
+	public setUserSettings(userSettings: UserSettings): void {
+		this.store.dispatch(UserSettingsAction.setUserSettings({ userSettings }))
+	}
+}
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.models.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.models.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4eacd56495066d2f8f7f7f3ae6d135d47014c6d6
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.models.ts
@@ -0,0 +1,7 @@
+/**
+ * Interface for the 'UserSettings' data
+ */
+export interface UserSettingsEntity {
+	id: string | number; // Primary ID
+	name: string;
+}
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c887fe17b046ec9affbcbc0fd2ad7c308df1fae6
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.spec.ts
@@ -0,0 +1,100 @@
+import { ApiError, createStateResource } from '@goofy-client/tech-shared';
+import { Action } from '@ngrx/store';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { createApiError } from '../../../../tech-shared/test/error';
+import { UserSettingsResource } from '../user-settings.model';
+import * as UserSettingsActions from './user-settings.actions';
+import { initialUserSettingsState, userSettingsReducer, UserSettingsState } from './user-settings.reducer';
+
+describe('User Settings Reducer', () => {
+
+	describe('unknown action', () => {
+
+		it('should return current state', () => {
+			const action: Action = {} as Action;
+
+			const result = userSettingsReducer(initialUserSettingsState, action);
+
+			expect(result).toBe(initialUserSettingsState);
+		})
+	})
+
+	describe('loadUserSettings', () => {
+		describe('on "loadUserSettings" action', () => {
+			it('should set loading to true', () => {
+				const action: Action = UserSettingsActions.loadUserSettings({ currentUser: createUserProfileResource() });
+
+				const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+				expect(state.userSettings.loading).toBeTruthy();
+			})
+		})
+	})
+
+	describe('on "loadUserSettingsSuccess"', () => {
+		const userSettings: UserSettingsResource = createUserSettingsResource();
+		const action: Action = UserSettingsActions.loadUserSettingsSuccess({ userSettings });
+
+		it('should set loaded resource', () => {
+			const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+			expect(state.userSettings).toEqual(createStateResource(userSettings));
+		})
+
+		it('should has property "notificationsSendFor"', () => {
+			const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+			expect(state.userSettings).toHaveProperty('resource.notificationsSendFor');
+		})
+	})
+
+	describe('on "loadUserSettingsFailure"', () => {
+		it('should set apiError', () => {
+			const apiError: ApiError = createApiError();
+			const action: Action = UserSettingsActions.loadUserSettingsFailure({ apiError });
+
+			const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+			expect(state.userSettings.error).toStrictEqual(apiError);
+		})
+	})
+
+	describe('setUserSettings', () => {
+
+		describe('on "setUserSettings" action', () => {
+
+			it('should set state resource to loading', () => {
+				const action: Action = UserSettingsActions.setUserSettings({ userSettings: createUserSettings() });
+
+				const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+				expect(state.userSettings.loading).toBeTruthy();
+			})
+		})
+
+		describe('on "setUserSettingsSuccess" action', () => {
+
+			const userSettingsResource: UserSettingsResource = createUserSettingsResource();
+			const action: Action = UserSettingsActions.setUserSettingsSuccess({ userSettings: userSettingsResource });
+
+			it('should set loaded resource', () => {
+				const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+				expect(state.userSettings).toEqual(createStateResource(userSettingsResource));
+			})
+		})
+
+		describe('on "setUserSettingsFailure" action', () => {
+
+			it('should set API Error', () => {
+				const apiError: ApiError = createApiError();
+				const action: Action = UserSettingsActions.setUserSettingsFailure({ apiError });
+
+				const state: UserSettingsState = userSettingsReducer(initialUserSettingsState, action);
+
+				expect(state.userSettings.error).toStrictEqual(apiError);
+			})
+		})
+	})
+})
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9ee7052bcaac3e302d41150bf0c2a6394a2c57ac
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.reducer.ts
@@ -0,0 +1,52 @@
+import { createEmptyStateResource, createErrorStateResource, createStateResource, StateResource } from '@goofy-client/tech-shared';
+import { Action, ActionReducer, createReducer, on } from '@ngrx/store';
+import { UserSettingsResource } from '../user-settings.model';
+import * as UserSettingsActions from './user-settings.actions';
+import { ApiErrorAction, LoadedUserSettingsAction } from './user-settings.actions';
+
+export const SETTINGS_FEATURE_KEY = 'UserSettingsState';
+
+export interface UserSettingsPartialState {
+	readonly [SETTINGS_FEATURE_KEY]: UserSettingsState;
+}
+
+export interface UserSettingsState {
+	userSettings: StateResource<UserSettingsResource>
+}
+
+export const initialUserSettingsState: UserSettingsState = {
+	userSettings: createEmptyStateResource()
+};
+
+const reducer: ActionReducer<UserSettingsState, Action> = createReducer(
+	initialUserSettingsState,
+	on(UserSettingsActions.loadUserSettings, (state: UserSettingsState): UserSettingsState => ({
+		...state,
+		userSettings: { ...state.userSettings, loading: true }
+	})),
+	on(UserSettingsActions.loadUserSettingsSuccess, (state: UserSettingsState, action: LoadedUserSettingsAction) => ({
+		...state,
+		userSettings: createStateResource<UserSettingsResource>(action.userSettings)
+	})),
+	on(UserSettingsActions.loadUserSettingsFailure, (state: UserSettingsState, action: ApiErrorAction) => ({
+		...state,
+		userSettings: createErrorStateResource<UserSettingsResource>(action.apiError)
+	})),
+
+	on(UserSettingsActions.setUserSettings, (state: UserSettingsState): UserSettingsState => ({
+		...state,
+		userSettings: { ...state.userSettings, loading: true }
+	})),
+	on(UserSettingsActions.setUserSettingsSuccess, (state: UserSettingsState, action: LoadedUserSettingsAction) => ({
+		...state,
+		userSettings: createStateResource<UserSettingsResource>(action.userSettings)
+	})),
+	on(UserSettingsActions.setUserSettingsFailure, (state: UserSettingsState, action: ApiErrorAction) => ({
+		...state,
+		userSettings: createErrorStateResource<UserSettingsResource>(action.apiError)
+	}))
+);
+
+export function userSettingsReducer(state: UserSettingsState, action: Action): UserSettingsState {
+	return reducer(state, action);
+}
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60ae1f81e3a3cf22b87c43b112363abf016b7178
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.spec.ts
@@ -0,0 +1,28 @@
+import { createStateResource, StateResource } from '@goofy-client/tech-shared';
+import { createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { UserSettingsResource } from '../user-settings.model';
+import { initialUserSettingsState, UserSettingsPartialState } from './user-settings.reducer';
+import * as UserSettingsSelectors from './user-settings.selectors';
+
+describe('UserSettings Selectors', () => {
+
+	let state: UserSettingsPartialState;
+
+	const userSettings: StateResource<UserSettingsResource> = createStateResource(createUserSettingsResource());
+
+	beforeEach(() => {
+		state = {
+			UserSettingsState: {
+				...initialUserSettingsState,
+				userSettings
+			}
+		}
+	})
+
+	describe('userSettingsSelector', () => {
+
+		it('should return userSettings from state', () => {
+			expect(UserSettingsSelectors.userSettings.projector(state.UserSettingsState)).toEqual(userSettings);
+		})
+	})
+})
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.ts b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8f5096de99e181cb89e81213a99d6d1931df6d45
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/+state/user-settings.selectors.ts
@@ -0,0 +1,8 @@
+import { StateResource } from '@goofy-client/tech-shared';
+import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store';
+import { UserSettingsResource } from '../user-settings.model';
+import { SETTINGS_FEATURE_KEY, UserSettingsState } from './user-settings.reducer';
+
+export const getUserSettingsState: MemoizedSelector<object, UserSettingsState> = createFeatureSelector<UserSettingsState>(SETTINGS_FEATURE_KEY);
+
+export const userSettings: MemoizedSelector<UserSettingsState, StateResource<UserSettingsResource>> = createSelector(getUserSettingsState, (state: UserSettingsState) => state.userSettings);
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings-shared.module.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings-shared.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1d384a3a513634113441b1dc9ddb2267274fd1da
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings-shared.module.ts
@@ -0,0 +1,24 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { EffectsModule } from '@ngrx/effects';
+import { StoreModule } from '@ngrx/store';
+import { UserSettingsEffects } from './+state/user-settings.effects';
+import { UserSettingsFacade } from './+state/user-settings.facade';
+import * as fromUserSettings from './+state/user-settings.reducer';
+
+@NgModule({
+	imports: [
+		CommonModule,
+		StoreModule.forFeature(
+			fromUserSettings.SETTINGS_FEATURE_KEY,
+			fromUserSettings.userSettingsReducer
+		),
+		EffectsModule.forFeature([UserSettingsEffects]),
+		StoreModule.forFeature(
+			fromUserSettings.SETTINGS_FEATURE_KEY,
+			fromUserSettings.userSettingsReducer
+		),
+	],
+	providers: [UserSettingsFacade],
+})
+export class UserSettingsSharedModule { }
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.linkrel.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.linkrel.ts
new file mode 100644
index 0000000000000000000000000000000000000000..45eb1e78d78171a1b3579ded1e35a01557be01da
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.linkrel.ts
@@ -0,0 +1,3 @@
+export enum UserSettingsLinkRel {
+	EDIT = 'edit',
+}
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.model.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2407b80dd1e27e3da5c8fc476e6e793c13ceef2d
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.model.ts
@@ -0,0 +1,12 @@
+import { Resource } from '@ngxp/rest';
+
+export enum NotificationsSendFor {
+	NONE = "NONE",
+	ALL = "ALL"
+}
+
+export interface UserSettings {
+	notificationsSendFor: string;
+}
+
+export interface UserSettingsResource extends UserSettings, Resource { }
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ce24b371135751e376ffb67b94962c7876e2fa3d
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.spec.ts
@@ -0,0 +1,78 @@
+import { mock, useFromMock } from '@goofy-client/test-utils';
+import { UserProfileLinkRel, UserProfileResource } from '@goofy-client/user-profile-shared';
+import { ResourceFactory } from '@ngxp/rest';
+import { cold, hot } from 'jest-marbles';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { UserSettingsLinkRel } from './user-settings.linkrel';
+import { UserSettings, UserSettingsResource } from './user-settings.model';
+import { UserSettingsRepository } from './user-settings.repository';
+
+describe('UserSettingsRepository', () => {
+	let repository: UserSettingsRepository;
+	let resourceFactory = mock(ResourceFactory);
+	let resourceWrapper = { get: jest.fn(), patch: jest.fn() };
+
+	beforeEach(() => {
+		repository = new UserSettingsRepository(useFromMock(resourceFactory));
+
+		resourceFactory.from.mockReturnValue(resourceWrapper);
+	})
+
+	describe('get user settings', () => {
+		const userProfileResource: UserProfileResource = createUserProfileResource();
+		const responseResource: UserProfileResource = createUserProfileResource();
+
+		beforeEach(() => {
+			resourceWrapper.get.mockReturnValue(hot('a', { a: responseResource }));
+		})
+
+		it('should call resourceFactory with resource', () => {
+			repository.getUserSettings(userProfileResource);
+
+			expect(resourceFactory.from).toHaveBeenCalledWith(userProfileResource);
+		})
+
+		it('should call resourceWrapper with link', () => {
+			repository.getUserSettings(userProfileResource);
+
+			expect(resourceWrapper.get).toHaveBeenCalledWith(UserProfileLinkRel.SETTINGS)
+		})
+
+		it('should return result', () => {
+			let result = repository.getUserSettings(userProfileResource);
+
+			expect(result).not.toBeNull();
+			expect(result).toBeObservable(cold('a', { a: responseResource }));
+		})
+	})
+
+	describe('set user settings', () => {
+		const userSettingsResource: UserSettingsResource = createUserSettingsResource();
+		const responseResource: UserProfileResource = createUserProfileResource();
+		const userSettings: UserSettings = createUserSettings();
+
+		beforeEach(() => {
+			resourceWrapper.patch.mockReturnValue(hot('a', { a: responseResource }));
+		})
+
+		it('should call resourceFactory with resource', () => {
+			repository.setUserSettings(userSettingsResource, userSettings);
+
+			expect(resourceFactory.from).toHaveBeenCalledWith(userSettingsResource);
+		})
+
+		it('should call resourceWrapper with link', () => {
+			repository.setUserSettings(userSettingsResource, userSettings);
+
+			expect(resourceWrapper.patch).toHaveBeenCalledWith(UserSettingsLinkRel.EDIT, userSettings)
+		})
+
+		it('should return result', () => {
+			let result = repository.setUserSettings(userSettingsResource, userSettings);
+
+			expect(result).not.toBeNull();
+			expect(result).toBeObservable(cold('a', { a: responseResource }));
+		})
+	})
+})
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a142e67c8d4ba45dc3a8ce37a1aafcc70fb9efe9
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.repository.ts
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import { UserProfileLinkRel, UserProfileResource } from '@goofy-client/user-profile-shared';
+import { ResourceFactory } from '@ngxp/rest';
+import { Observable } from 'rxjs';
+import { UserSettingsLinkRel } from './user-settings.linkrel';
+import { UserSettings, UserSettingsResource } from './user-settings.model';
+
+@Injectable({ providedIn: 'root' })
+export class UserSettingsRepository {
+
+	constructor(private resourceFactory: ResourceFactory) { }
+
+	public getUserSettings(userProfileResource: UserProfileResource): Observable<UserSettingsResource> {
+		return this.resourceFactory.from(userProfileResource).get(UserProfileLinkRel.SETTINGS);
+	}
+
+	public setUserSettings(userSettingsResource: UserSettingsResource, userSettings: UserSettings): Observable<UserSettingsResource> {
+		return this.resourceFactory.from(userSettingsResource).patch(UserSettingsLinkRel.EDIT, userSettings);
+	}
+}
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.spec.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ec12c7e2c0d69cc04bba9923d0c1b3183690040c
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.spec.ts
@@ -0,0 +1,71 @@
+import { createEmptyStateResource, createStateResource, StateResource } from '@goofy-client/tech-shared';
+import { mock, Mock, useFromMock } from '@goofy-client/test-utils';
+import { UserProfileResource, UserProfileService } from '@goofy-client/user-profile-shared';
+import { cold, hot } from 'jest-marbles';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { Observable } from 'rxjs';
+import { UserSettingsFacade } from './+state/user-settings.facade';
+import { UserSettings, UserSettingsResource } from './user-settings.model';
+import { UserSettingsService } from './user-settings.service';
+
+describe('UserSettingsService', () => {
+	let facade: Mock<UserSettingsFacade>;
+	let userProfileService: Mock<UserProfileService>;
+
+	let service: UserSettingsService;
+
+	beforeEach(() => {
+		facade = mock(UserSettingsFacade);
+		userProfileService = mock(UserProfileService);
+
+		service = new UserSettingsService(useFromMock(facade), useFromMock(userProfileService));
+	});
+
+	it('should be created', () => {
+		expect(service).toBeTruthy();
+	});
+
+	describe('get user settings', () => {
+		const userProfileResource: UserProfileResource = createUserProfileResource();
+		const stateResourceCU = createStateResource(createUserSettingsResource());
+		const emptyStateResourceCU = createEmptyStateResource<UserProfileResource>(true);
+
+		beforeEach(() => {
+			const stateResourceUP: StateResource<UserProfileResource> = createStateResource(userProfileResource);
+			userProfileService.getCurrentUser.mockReturnValue(hot('a', { a: stateResourceUP }));
+
+			facade.getUserSettings.mockReturnValue(hot('-a', { a: stateResourceCU }));
+		})
+
+		it('should call userProfileService.getCurrentUser', () => {
+			service.getUserSettings();
+
+			expect(userProfileService.getCurrentUser).toHaveBeenCalled();
+		})
+
+		it.skip('should load user settings from facade', (done) => {
+			service.getUserSettings().subscribe(() => {
+				expect(facade.loadUserSettings).toHaveBeenCalledWith(userProfileResource);
+				done();
+			});
+		})
+
+		it('should return user settings', () => {
+			const userSettings$: Observable<StateResource<UserSettingsResource>> = service.getUserSettings();
+
+			expect(userSettings$).toBeObservable(cold('ab', { a: emptyStateResourceCU, b: stateResourceCU }));
+		})
+
+	})
+
+	describe('set UserSettings', () => {
+		it('should call set method in facade', () => {
+			const userSettings: UserSettings = createUserSettings();
+
+			service.setUserSettings(userSettings);
+
+			expect(facade.setUserSettings).toHaveBeenCalledWith(userSettings);
+		})
+	})
+});
diff --git a/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.ts b/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..29ddc9c17fdd4091ba6d76b1518abefac4a90705
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/lib/user-settings.service.ts
@@ -0,0 +1,32 @@
+import { Injectable } from '@angular/core';
+import { createEmptyStateResource, doIfLoadingRequired, StateResource } from '@goofy-client/tech-shared';
+import { UserProfileService } from '@goofy-client/user-profile-shared';
+import { combineLatest, Observable } from 'rxjs';
+import { map, startWith, tap } from 'rxjs/operators';
+import { UserSettingsFacade } from './+state/user-settings.facade';
+import { UserSettings, UserSettingsResource } from './user-settings.model';
+
+@Injectable({ providedIn: 'root' })
+export class UserSettingsService {
+
+	constructor(
+		private userSettingsFacade: UserSettingsFacade,
+		private userProfileService: UserProfileService,
+	) { }
+
+	public getUserSettings(): Observable<StateResource<UserSettingsResource>> {
+		return combineLatest([this.userProfileService.getCurrentUser(), this.userSettingsFacade.getUserSettings()]).pipe(
+			tap(([userProfile, userSettings]) => doIfLoadingRequired(userSettings, () => {
+				if (userProfile.resource) {
+					this.userSettingsFacade.loadUserSettings(userProfile.resource);
+				}
+			})),
+			map(([, userSettings]) => userSettings),
+			startWith(createEmptyStateResource<UserSettingsResource>(true))
+		);
+	}
+
+	public setUserSettings(userSettings: UserSettings): void {
+		this.userSettingsFacade.setUserSettings(userSettings);
+	}
+}
diff --git a/goofy-client/libs/user-settings-shared/src/test-setup.ts b/goofy-client/libs/user-settings-shared/src/test-setup.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ffbe3a552ab7905a5e86fad93e87c7bc1d3abed7
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/src/test-setup.ts
@@ -0,0 +1,14 @@
+import 'jest-preset-angular/setup-jest';
+
+import { getTestBed } from '@angular/core/testing';
+import {
+	BrowserDynamicTestingModule,
+	platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+getTestBed().resetTestEnvironment();
+getTestBed().initTestEnvironment(
+	BrowserDynamicTestingModule,
+	platformBrowserDynamicTesting(),
+	{ teardown: { destroyAfterEach: false } }
+);
diff --git a/goofy-client/libs/user-settings-shared/test/user-settings.ts b/goofy-client/libs/user-settings-shared/test/user-settings.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5e10134a7c4e119acf4627c25934a3904ea0edbc
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/test/user-settings.ts
@@ -0,0 +1,13 @@
+import { toResource } from 'libs/tech-shared/test/resource';
+import { NotificationsSendFor, UserSettings, UserSettingsResource } from '../src/lib/user-settings.model';
+
+export function createUserSettingsResource(linkRelations: string[] = []): UserSettingsResource {
+	return toResource(createUserSettings(), linkRelations);
+}
+
+export function createUserSettings(): UserSettings {
+	return {
+		notificationsSendFor: NotificationsSendFor.ALL
+	}
+}
+
diff --git a/goofy-client/libs/user-settings-shared/tsconfig.json b/goofy-client/libs/user-settings-shared/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..3d3a2a0498aafea3513d0d915e99d166d927fbe0
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/tsconfig.json
@@ -0,0 +1,16 @@
+{
+	"extends": "../../tsconfig.base.json",
+	"files": [],
+	"include": [],
+	"references": [
+		{
+			"path": "./tsconfig.lib.json"
+		},
+		{
+			"path": "./tsconfig.spec.json"
+		}
+	],
+	"compilerOptions": {
+		"target": "es2020"
+	}
+}
diff --git a/goofy-client/libs/user-settings-shared/tsconfig.lib.json b/goofy-client/libs/user-settings-shared/tsconfig.lib.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2a53880f8274e73d8c264e347047cbd8c1f1cf8
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/tsconfig.lib.json
@@ -0,0 +1,12 @@
+{
+	"extends": "./tsconfig.json",
+	"compilerOptions": {
+		"outDir": "../../dist/out-tsc",
+		"declaration": true,
+		"declarationMap": true,
+		"inlineSources": true,
+		"types": []
+	},
+	"exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"],
+	"include": ["**/*.ts"]
+}
diff --git a/goofy-client/libs/user-settings-shared/tsconfig.spec.json b/goofy-client/libs/user-settings-shared/tsconfig.spec.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6c95196f6ff5249f87bfce3a787b520a26d8a67
--- /dev/null
+++ b/goofy-client/libs/user-settings-shared/tsconfig.spec.json
@@ -0,0 +1,10 @@
+{
+	"extends": "./tsconfig.json",
+	"compilerOptions": {
+		"outDir": "../../dist/out-tsc",
+		"module": "commonjs",
+		"types": ["jest", "node"]
+	},
+	"files": ["src/test-setup.ts"],
+	"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
+}
diff --git a/goofy-client/libs/user-settings/.eslintrc.json b/goofy-client/libs/user-settings/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..28f19b630511beab4ad3ff61ffce5a45f7430728
--- /dev/null
+++ b/goofy-client/libs/user-settings/.eslintrc.json
@@ -0,0 +1,36 @@
+{
+	"extends": ["../../.eslintrc.json"],
+	"ignorePatterns": ["!**/*"],
+	"overrides": [
+		{
+			"files": ["*.ts"],
+			"extends": [
+				"plugin:@nrwl/nx/angular",
+				"plugin:@angular-eslint/template/process-inline-templates"
+			],
+			"rules": {
+				"@angular-eslint/directive-selector": [
+					"error",
+					{
+						"type": "attribute",
+						"prefix": "goofyClient",
+						"style": "camelCase"
+					}
+				],
+				"@angular-eslint/component-selector": [
+					"error",
+					{
+						"type": "element",
+						"prefix": "goofy-client",
+						"style": "kebab-case"
+					}
+				]
+			}
+		},
+		{
+			"files": ["*.html"],
+			"extends": ["plugin:@nrwl/nx/angular-template"],
+			"rules": {}
+		}
+	]
+}
diff --git a/goofy-client/libs/user-settings/README.md b/goofy-client/libs/user-settings/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9c5e3d238e40e7a12d88bf3a608b8e8211bb8047
--- /dev/null
+++ b/goofy-client/libs/user-settings/README.md
@@ -0,0 +1,7 @@
+# user-settings
+
+This library was generated with [Nx](https://nx.dev).
+
+## Running unit tests
+
+Run `nx test user-settings` to execute the unit tests.
diff --git a/goofy-client/libs/user-settings/jest.config.ts b/goofy-client/libs/user-settings/jest.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..770771ca188c94a6c6ed7526893d002b9df67976
--- /dev/null
+++ b/goofy-client/libs/user-settings/jest.config.ts
@@ -0,0 +1,22 @@
+/* eslint-disable */
+export default {
+	displayName: 'user-settings',
+	preset: '../../jest.preset.js',
+	setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
+	globals: {
+		'ts-jest': {
+			tsconfig: '<rootDir>/tsconfig.spec.json',
+			stringifyContentPathRegex: '\\.(html|svg)$',
+		},
+	},
+	coverageDirectory: '../../coverage/libs/user-settings',
+	transform: {
+		'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
+	},
+	transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
+	snapshotSerializers: [
+		'jest-preset-angular/build/serializers/no-ng-attributes',
+		'jest-preset-angular/build/serializers/ng-snapshot',
+		'jest-preset-angular/build/serializers/html-comment',
+	],
+};
diff --git a/goofy-client/libs/user-settings/src/index.ts b/goofy-client/libs/user-settings/src/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ba9f3be48abca118db96c0fabea35ac298590866
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/index.ts
@@ -0,0 +1,4 @@
+export * from './lib/user-settings-container/user-settings-container.component';
+export * from './lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component';
+export * from './lib/user-settings.module';
+
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.html b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..7cff27785933adb77a43e9155b796fd3efb9d9d8
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.html
@@ -0,0 +1,16 @@
+<goofy-client-icon-button-with-spinner icon="settings" toolTip="Einstellungen"
+	[matMenuTriggerFor]="settingsMenu">
+</goofy-client-icon-button-with-spinner>
+
+<mat-menu #settingsMenu="matMenu">
+	<div class="menu-container" (click)="$event.stopPropagation()">
+		<goofy-client-user-settings-email-benachrichtigung
+			[userSettings$]="userSettings$"
+			(valueChanged)="changeNotificationsSendFor($event)"
+		></goofy-client-user-settings-email-benachrichtigung>
+		<goofy-client-user-settings-darkmode
+			[darkMode$]="darkMode$"
+			(darkModeEmitter)="changeColorMode($event)"
+		></goofy-client-user-settings-darkmode>
+	</div>
+</mat-menu>
diff --git a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.scss b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.scss
similarity index 50%
rename from goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.scss
rename to goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.scss
index 982d28ee457184d07da4cb2d8271bc6fd7a8f576..e15dab43b6e1199516db6bca6fe3c9ad2574d47e 100644
--- a/goofy-client/libs/navigation/src/lib/header-container/header/settings/settings.component.scss
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.scss
@@ -2,6 +2,7 @@
 	margin: 12px 16px;
 }
 
-goofy-client-icon-button-with-spinner {
+goofy-client-icon-button-with-spinner,
+mat-slide-toggle {
 	display: block;
 }
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.spec.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d11f9673e482b3b32a9c60b9f203382028210041
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.spec.ts
@@ -0,0 +1,77 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatMenuModule } from '@angular/material/menu';
+import { AppService } from '@goofy-client/app-shared';
+import { mock } from '@goofy-client/test-utils';
+import { IconButtonWithSpinnerComponent } from '@goofy-client/ui';
+import { UserSettingsService } from '@goofy-client/user-settings-shared';
+import { NotificationsSendFor } from 'libs/user-settings-shared/src/lib/user-settings.model';
+import { MockComponent } from 'ng-mocks';
+import { BehaviorSubject } from 'rxjs';
+import { UserSettingsContainerComponent } from './user-settings-container.component';
+import { UserSettingsDarkmodeComponent } from './user-settings-darkmode/user-settings-darkmode.component';
+import { UserSettingsEmailBenachrichtigungComponent } from './user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component';
+
+describe('UserSettingsContainerComponent', () => {
+	let component: UserSettingsContainerComponent;
+	let fixture: ComponentFixture<UserSettingsContainerComponent>;
+
+	const darkModeSubj: BehaviorSubject<boolean> = new BehaviorSubject(false);
+	const appService = { ...mock(AppService), getDarkMode: () => darkModeSubj };
+	const userSettingsService = { ...mock(UserSettingsService), setUserSettings: jest.fn() };
+
+	beforeEach(async () => {
+		await TestBed.configureTestingModule({
+			imports: [MatMenuModule],
+			declarations: [
+				UserSettingsContainerComponent,
+				MockComponent(UserSettingsDarkmodeComponent),
+				MockComponent(UserSettingsEmailBenachrichtigungComponent),
+				MockComponent(IconButtonWithSpinnerComponent)
+			],
+			providers: [
+				{
+					provide: AppService,
+					useValue: appService,
+				},
+				{
+					provide: UserSettingsService,
+					useValue: userSettingsService
+				}
+			],
+		});
+	});
+
+	beforeEach(() => {
+		fixture = TestBed.createComponent(UserSettingsContainerComponent);
+		component = fixture.componentInstance;
+		fixture.detectChanges();
+	});
+
+	it('should create', () => {
+		expect(component).toBeTruthy();
+	});
+
+	describe('change color mode', () => {
+
+		it('should call app service', () => {
+			component.changeColorMode(true);
+
+			expect(appService.setDarkMode).toHaveBeenCalledWith(true);
+		})
+	})
+
+	describe('change notifications send for', () => {
+
+		it('should call service with ALL', () => {
+			component.changeNotificationsSendFor(true);
+
+			expect(userSettingsService.setUserSettings).toHaveBeenCalledWith({ notificationsSendFor: NotificationsSendFor.ALL });
+		})
+
+		it('should call service with NONE', () => {
+			component.changeNotificationsSendFor(false);
+
+			expect(userSettingsService.setUserSettings).toHaveBeenCalledWith({ notificationsSendFor: NotificationsSendFor.NONE });
+		})
+	})
+});
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3ebe11daa5b45cdd973c475cd500f065bc3581d2
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-container.component.ts
@@ -0,0 +1,61 @@
+import { DOCUMENT } from '@angular/common';
+import { Component, Inject, OnInit, Renderer2 } from '@angular/core';
+import { AppService, localStorageDark } from '@goofy-client/app-shared';
+import { StateResource } from '@goofy-client/tech-shared';
+import { UserSettingsService } from '@goofy-client/user-settings-shared';
+import { NotificationsSendFor, UserSettings, UserSettingsResource } from 'libs/user-settings-shared/src/lib/user-settings.model';
+import { Observable, of } from 'rxjs';
+
+@Component({
+	selector: 'goofy-client-user-settings-container',
+	templateUrl: './user-settings-container.component.html',
+	styleUrls: ['./user-settings-container.component.scss'],
+})
+export class UserSettingsContainerComponent implements OnInit {
+	darkMode$: Observable<boolean> = of(true);
+	userSettings$: Observable<StateResource<UserSettingsResource>>;
+
+	constructor(
+		private renderer: Renderer2,
+		private appService: AppService,
+		private userSettingsService: UserSettingsService,
+		@Inject(DOCUMENT) private document: Document
+	) {
+		this.darkMode$ = this.appService.getDarkMode();
+
+		this.subscribeToDarkMode();
+	}
+
+	ngOnInit(): void {
+		this.userSettings$ = this.userSettingsService.getUserSettings();
+	}
+
+	private subscribeToDarkMode(): void {
+		this.darkMode$.subscribe((darkMode) =>
+			darkMode
+				? this.addClass(localStorageDark)
+				: this.removeClass(localStorageDark)
+		);
+	}
+
+	private addClass(styleClass: string): void {
+		this.renderer.addClass(this.document.body, styleClass);
+	}
+
+	private removeClass(styleClass: string): void {
+		this.renderer.removeClass(this.document.body, styleClass);
+	}
+
+	changeColorMode(darkMode: boolean): void {
+		this.appService.setDarkMode(darkMode);
+	}
+
+	changeNotificationsSendFor(toggleValue: boolean): void {
+		this.userSettingsService.setUserSettings(this.createUserSettings(toggleValue));
+	}
+
+	private createUserSettings(toggleValue: boolean): UserSettings {
+		const notificationsSendFor: NotificationsSendFor = toggleValue ? NotificationsSendFor.ALL : NotificationsSendFor.NONE;
+		return { notificationsSendFor };
+	}
+}
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.html b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..07a006c57442bef409a85437b10a68fde2f5c680
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.html
@@ -0,0 +1,6 @@
+<mat-slide-toggle
+	color="primary"
+	[checked]="darkMode$ | async"
+	(change)="darkModeEmitter.emit($event.checked)"
+	>Dark Mode
+</mat-slide-toggle>
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.scss b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.spec.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f333224d4ba89c44239501605915654454dcfa27
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { UiModule } from '@goofy-client/ui';
+import { UserSettingsDarkmodeComponent } from './user-settings-darkmode.component';
+
+describe('UserSettingsDarkmodeComponent', () => {
+	let component: UserSettingsDarkmodeComponent;
+	let fixture: ComponentFixture<UserSettingsDarkmodeComponent>;
+
+	beforeEach(async () => {
+		await TestBed.configureTestingModule({
+			imports: [UiModule],
+			declarations: [UserSettingsDarkmodeComponent],
+		}).compileComponents();
+
+		fixture = TestBed.createComponent(UserSettingsDarkmodeComponent);
+		component = fixture.componentInstance;
+		fixture.detectChanges();
+	});
+
+	it('should create', () => {
+		expect(component).toBeTruthy();
+	});
+});
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..651132cf8620c19aa5b6375164247bf99ddb0384
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-darkmode/user-settings-darkmode.component.ts
@@ -0,0 +1,14 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Observable, of } from 'rxjs';
+
+@Component({
+	selector: 'goofy-client-user-settings-darkmode',
+	templateUrl: './user-settings-darkmode.component.html',
+	styleUrls: ['./user-settings-darkmode.component.scss'],
+})
+export class UserSettingsDarkmodeComponent {
+	@Input() darkMode$: Observable<boolean> = of(true);
+
+	@Output() public darkModeEmitter: EventEmitter<boolean> =
+		new EventEmitter();
+}
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.html b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..90823c5225e8680fc0f3c4e8f2d59ada0db9366e
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.html
@@ -0,0 +1,8 @@
+<ng-container *ngIf="(userSettings$ | async)?.resource as userSettings">
+	<mat-slide-toggle data-test-id="toggle-notifications-send-for"
+		color="primary"
+		matTooltip="Benachrichtigung per E-Mail bei Eingang eines Antrags"
+		[checked]="getToggleStatus(userSettings)"
+		(change)="valueChanged.emit($event.checked)">Benachrichtigung per E-Mail
+	</mat-slide-toggle>
+</ng-container>
\ No newline at end of file
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.scss b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..92276dfe14738302abcf74e348103b1dfb94c9fe
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.scss
@@ -0,0 +1,3 @@
+mat-slide-toggle {
+	margin-bottom: 0.5rem;
+}
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.spec.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..84969ed2659f95fb7dd76e3fd5eb56be1719b2f2
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.spec.ts
@@ -0,0 +1,70 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatRippleModule } from '@angular/material/core';
+import { MatMenuModule } from '@angular/material/menu';
+import { MatSlideToggle } from '@angular/material/slide-toggle';
+import { createStateResource } from '@goofy-client/tech-shared';
+
+import { dispatchEventFromFixture, mock } from '@goofy-client/test-utils';
+import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { NotificationsSendFor } from 'libs/user-settings-shared/src/lib/user-settings.model';
+import { createUserSettings, createUserSettingsResource } from 'libs/user-settings-shared/test/user-settings';
+import { of } from 'rxjs';
+import { EventEmitter } from 'stream';
+import { UserSettingsEmailBenachrichtigungComponent } from './user-settings-email-benachrichtigung.component';
+
+describe('UserSettingsEmailBenachrichtigungComponent', () => {
+	let component: UserSettingsEmailBenachrichtigungComponent;
+	let fixture: ComponentFixture<UserSettingsEmailBenachrichtigungComponent>;
+
+	const toggle: string = getDataTestIdOf('toggle-notifications-send-for');
+	const userSettings = createUserSettings();
+
+	beforeEach(async () => {
+		await TestBed.configureTestingModule({
+			imports: [MatMenuModule, MatRippleModule],
+			declarations: [UserSettingsEmailBenachrichtigungComponent, MatSlideToggle],
+		}).compileComponents();
+
+		fixture = TestBed.createComponent(
+			UserSettingsEmailBenachrichtigungComponent
+		);
+		component = fixture.componentInstance;
+		component.userSettings$ = of(createStateResource(createUserSettingsResource()));
+		component.valueChanged = { ...<any>mock(EventEmitter), emit: jest.fn() };
+		fixture.detectChanges();
+	});
+
+	it('should create', () => {
+		expect(component).toBeTruthy();
+	});
+
+	it('should show toggle', () => {
+		const element = fixture.nativeElement.querySelector(toggle);
+
+		expect(element).toBeInstanceOf(HTMLElement);
+	})
+
+	describe('toggle status', () => {
+		it('should be set if userSettings.notificationsSendFor is ALL', () => {
+			userSettings.notificationsSendFor = NotificationsSendFor.ALL;
+
+			const result: boolean = component.getToggleStatus(userSettings);
+
+			expect(result).toBeTruthy();
+		})
+
+		it('should not be set if userSettings.notificationsSendFor is NONE', () => {
+			userSettings.notificationsSendFor = NotificationsSendFor.NONE;
+
+			const result: boolean = component.getToggleStatus(userSettings);
+
+			expect(result).toBeFalsy();
+		})
+
+		it('should emit value if toggled', () => {
+			dispatchEventFromFixture(fixture, toggle, 'change');
+
+			expect(component.valueChanged.emit).toHaveBeenCalled();
+		})
+	})
+});
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.ts b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..adb1df1f939759d85464ac9503323a94759f55c2
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component.ts
@@ -0,0 +1,18 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { StateResource } from '@goofy-client/tech-shared';
+import { NotificationsSendFor, UserSettings, UserSettingsResource } from '@goofy-client/user-settings-shared';
+import { Observable } from 'rxjs';
+
+@Component({
+	selector: 'goofy-client-user-settings-email-benachrichtigung',
+	templateUrl: './user-settings-email-benachrichtigung.component.html',
+	styleUrls: ['./user-settings-email-benachrichtigung.component.scss'],
+})
+export class UserSettingsEmailBenachrichtigungComponent {
+	@Input() userSettings$: Observable<StateResource<UserSettingsResource>>;
+	@Output() valueChanged: EventEmitter<boolean> = new EventEmitter();
+
+	public getToggleStatus(userSettings: UserSettings): boolean {
+		return userSettings.notificationsSendFor === NotificationsSendFor.ALL;
+	}
+}
diff --git a/goofy-client/libs/user-settings/src/lib/user-settings.module.ts b/goofy-client/libs/user-settings/src/lib/user-settings.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..79c603fe449e56a1414bd9eec6ae65bc3aa9672e
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/lib/user-settings.module.ts
@@ -0,0 +1,25 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { UiModule } from '@goofy-client/ui';
+import { UserSettingsSharedModule } from '@goofy-client/user-settings-shared';
+import { UserSettingsContainerComponent } from './user-settings-container/user-settings-container.component';
+import { UserSettingsDarkmodeComponent } from './user-settings-container/user-settings-darkmode/user-settings-darkmode.component';
+import { UserSettingsEmailBenachrichtigungComponent } from './user-settings-container/user-settings-email-benachrichtigung/user-settings-email-benachrichtigung.component';
+
+@NgModule({
+	imports: [
+		CommonModule,
+		UiModule,
+		UserSettingsSharedModule
+	],
+	declarations: [
+		UserSettingsContainerComponent,
+		UserSettingsEmailBenachrichtigungComponent,
+		UserSettingsDarkmodeComponent,
+	],
+	exports: [
+		UserSettingsContainerComponent,
+		UserSettingsEmailBenachrichtigungComponent,
+	],
+})
+export class UserSettingsModule {}
diff --git a/goofy-client/libs/user-settings/src/test-setup.ts b/goofy-client/libs/user-settings/src/test-setup.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08ef82b5d5efa87cb27257314075f6a16eb7a63e
--- /dev/null
+++ b/goofy-client/libs/user-settings/src/test-setup.ts
@@ -0,0 +1,14 @@
+import 'jest-preset-angular/setup-jest';
+
+import { getTestBed } from '@angular/core/testing';
+import {
+	BrowserDynamicTestingModule,
+	platformBrowserDynamicTesting,
+} from '@angular/platform-browser-dynamic/testing';
+
+getTestBed().resetTestEnvironment();
+getTestBed().initTestEnvironment(
+	BrowserDynamicTestingModule,
+	platformBrowserDynamicTesting(),
+	{ teardown: { destroyAfterEach: false } }
+);
diff --git a/goofy-client/libs/user-settings/tsconfig.json b/goofy-client/libs/user-settings/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..3d3a2a0498aafea3513d0d915e99d166d927fbe0
--- /dev/null
+++ b/goofy-client/libs/user-settings/tsconfig.json
@@ -0,0 +1,16 @@
+{
+	"extends": "../../tsconfig.base.json",
+	"files": [],
+	"include": [],
+	"references": [
+		{
+			"path": "./tsconfig.lib.json"
+		},
+		{
+			"path": "./tsconfig.spec.json"
+		}
+	],
+	"compilerOptions": {
+		"target": "es2020"
+	}
+}
diff --git a/goofy-client/libs/user-settings/tsconfig.lib.json b/goofy-client/libs/user-settings/tsconfig.lib.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2a53880f8274e73d8c264e347047cbd8c1f1cf8
--- /dev/null
+++ b/goofy-client/libs/user-settings/tsconfig.lib.json
@@ -0,0 +1,12 @@
+{
+	"extends": "./tsconfig.json",
+	"compilerOptions": {
+		"outDir": "../../dist/out-tsc",
+		"declaration": true,
+		"declarationMap": true,
+		"inlineSources": true,
+		"types": []
+	},
+	"exclude": ["src/test-setup.ts", "**/*.spec.ts", "**/*.test.ts"],
+	"include": ["**/*.ts"]
+}
diff --git a/goofy-client/libs/user-settings/tsconfig.spec.json b/goofy-client/libs/user-settings/tsconfig.spec.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6c95196f6ff5249f87bfce3a787b520a26d8a67
--- /dev/null
+++ b/goofy-client/libs/user-settings/tsconfig.spec.json
@@ -0,0 +1,10 @@
+{
+	"extends": "./tsconfig.json",
+	"compilerOptions": {
+		"outDir": "../../dist/out-tsc",
+		"module": "commonjs",
+		"types": ["jest", "node"]
+	},
+	"files": ["src/test-setup.ts"],
+	"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
+}
diff --git a/goofy-client/libs/vorgang/src/lib/vorgang.module.ts b/goofy-client/libs/vorgang/src/lib/vorgang.module.ts
index 97443528a9bf246bf26f24fceae2859787daf3ed..49f433b03c481402f1680915ed115f5170cd5c7b 100644
--- a/goofy-client/libs/vorgang/src/lib/vorgang.module.ts
+++ b/goofy-client/libs/vorgang/src/lib/vorgang.module.ts
@@ -20,7 +20,7 @@ const routes: Routes = [
 	{
 		path: '',
 		component: VorgangListPageContainerComponent,
-		title: 'Vorgang-Liste | Alfa'
+		title: 'Alle Vorgänge | Alfa'
 	},
 	{
 		path: 'search/:search',
@@ -40,7 +40,7 @@ const routes: Routes = [
 	{
 		path: 'vorgang/:vorgangWithEingangUrl',
 		loadChildren: () => import('@goofy-client/vorgang-detail').then(m => m.VorgangDetailModule),
-		title: 'Vorgang-Detailseite | Alfa'
+		title: 'Details zum Vorgang | Alfa'
 	},
 ];
 
diff --git a/goofy-client/pom.xml b/goofy-client/pom.xml
index 641ca104804688f78f5e3ab96b556a2dc59bedda..45e6b5587379e4660ece10d816b5561dd8bd22c4 100644
--- a/goofy-client/pom.xml
+++ b/goofy-client/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>de.itvsh.ozg</groupId>
 		<artifactId>goofy</artifactId>
-		<version>0.31.0-SNAPSHOT</version>
+		<version>0.32.0-SNAPSHOT</version>
 	</parent>
 
     <modelVersion>4.0.0</modelVersion>
diff --git a/goofy-client/proxy.conf.json b/goofy-client/proxy.conf.json
index 4bc3d0b5262907841d1fcb13583bd2839e203860..34bc6ac9ced56d91af0347aeee18be29dae9ec09 100644
--- a/goofy-client/proxy.conf.json
+++ b/goofy-client/proxy.conf.json
@@ -7,5 +7,17 @@
 		},
 		"secure": false,
 		"logLevel": "debug"
+	},
+	"/usermanager/api": {
+		"target": {
+			"host": "localhost",
+			"port": 9092,
+			"protocol": "http:"
+		},
+		"pathRewrite": {
+			"^/usermanager": ""
+		},
+		"secure": false,
+		"logLevel": "debug"
 	}
 }
\ No newline at end of file
diff --git a/goofy-client/tsconfig.base.json b/goofy-client/tsconfig.base.json
index 873d101e70c97d2085574c4e33766f3275aac671..21cae37080c26111bd62cbc7c7f6c6314a54e33a 100644
--- a/goofy-client/tsconfig.base.json
+++ b/goofy-client/tsconfig.base.json
@@ -57,6 +57,10 @@
 			"@goofy-client/user-profile-shared": [
 				"libs/user-profile-shared/src/index.ts"
 			],
+			"@goofy-client/user-settings": ["libs/user-settings/src/index.ts"],
+			"@goofy-client/user-settings-shared": [
+				"libs/user-settings-shared/src/index.ts"
+			],
 			"@goofy-client/vorgang": ["libs/vorgang/src/index.ts"],
 			"@goofy-client/vorgang-detail": [
 				"libs/vorgang-detail/src/index.ts"
diff --git a/goofy-server/pom.xml b/goofy-server/pom.xml
index ba4e53191ef5670c93764305b9e4d0a8c80f00fe..24c74564ce454a3a77092d6d223c435fd550431e 100644
--- a/goofy-server/pom.xml
+++ b/goofy-server/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>de.itvsh.ozg</groupId>
 		<artifactId>goofy</artifactId>
-		<version>0.31.0-SNAPSHOT</version>
+		<version>0.32.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>goofy-server</artifactId>
diff --git a/pom.xml b/pom.xml
index 6315b873457a7e59e27a0329eb9ad3ed0d470dc5..51643ab3571b1d4e1ee313fb5279b0915610573c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,14 +5,14 @@
 
 	<groupId>de.itvsh.ozg</groupId>
 	<artifactId>goofy</artifactId>
-	<version>0.31.0-SNAPSHOT</version>
+	<version>0.32.0-SNAPSHOT</version>
 	<name>Goofy Parent</name>
 	<packaging>pom</packaging>
 
 	<parent>
 		<groupId>de.itvsh.kop.common</groupId>
 		<artifactId>kop-common-parent</artifactId>
-		<version>1.1.5</version>
+		<version>1.2.1</version>
 	</parent>
 
 	<modules>
@@ -24,7 +24,7 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-		<pluto.version>0.31.0-SNAPSHOT</pluto.version>
+		<pluto.version>0.32.0-SNAPSHOT</pluto.version>
 		<jsoup.version>1.15.1</jsoup.version>
 	</properties>