diff --git a/web/settings/user-settings-list.css b/web/settings/user-settings-list.css
new file mode 100644
--- /dev/null
+++ b/web/settings/user-settings-list.css
@@ -0,0 +1,10 @@
+.container {
+ min-width: 160px;
+}
+
+.userSettingsList {
+ display: flex;
+ flex-direction: column;
+ row-gap: 16px;
+ padding: 16px;
+}
diff --git a/web/settings/user-settings-list.react.js b/web/settings/user-settings-list.react.js
new file mode 100644
--- /dev/null
+++ b/web/settings/user-settings-list.react.js
@@ -0,0 +1,92 @@
+// @flow
+
+import * as React from 'react';
+
+import { useDispatch } from 'lib/utils/redux-utils.js';
+
+import UserSettingsListItem from './user-settings-list-item.react.js';
+import css from './user-settings-list.css';
+import PanelHeader from '../components/panel-header.react.js';
+import Panel, { type PanelData } from '../components/panel.react.js';
+import { updateNavInfoActionType } from '../redux/action-types.js';
+import { useStaffCanSee } from '../utils/staff-utils.js';
+
+function UserSettingsList(): React.Node {
+ const dispatch = useDispatch();
+
+ const staffCanSee = useStaffCanSee();
+
+ const onClickAccountSettings = React.useCallback(() => {
+ dispatch({
+ type: updateNavInfoActionType,
+ payload: { tab: 'settings', settingsSection: 'account' },
+ });
+ }, [dispatch]);
+
+ const onClickKeyservers = React.useCallback(() => {
+ dispatch({
+ type: updateNavInfoActionType,
+ payload: { tab: 'settings', settingsSection: 'keyservers' },
+ });
+ }, [dispatch]);
+
+ const onClickDangerZone = React.useCallback(() => {
+ dispatch({
+ type: updateNavInfoActionType,
+ payload: { tab: 'settings', settingsSection: 'danger-zone' },
+ });
+ }, [dispatch]);
+
+ const keyserverSettingsListItem = React.useMemo(() => {
+ if (!staffCanSee) {
+ return null;
+ }
+
+ return (
+