From 335486952521d336154f3de92c73264e0bf13475 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Nov 2025 02:23:58 +0000 Subject: [PATCH] refactor(web): redesign Settings components with consistent design system Created a comprehensive redesign of all settings-related components to provide: **New Shared Components:** - SettingSection: Wrapper for consistent section layout with titles and actions - SettingGroup: Groups related settings with optional separators - SettingRow: Standardized label/control layout with optional tooltips - SettingTable: Consistent table styling for data lists **Key Improvements:** - Unified spacing and typography across all sections - Consistent form field layouts (label on left, control on right) - Better visual hierarchy with proper section/group organization - Standardized button variants (removed deprecated color="primary") - Improved mobile responsiveness with better wrapping - Added keyboard support (Enter key) for tag inputs - Better semantic HTML structure **Refactored Components:** - PreferencesSection: Clean layout with proper grouping - InstanceSection: Organized settings into logical groups - StorageSection: Improved S3 configuration display - MyAccountSection: Enhanced profile card layout - UserSessionsSection: Converted to table component - AccessTokenSection: Converted to table component - MemberSection: Converted to table component with improved actions - WebhookSection: Converted to table component - SSOSection: Converted to table component with better title support - MemoRelatedSettings: Improved tag management UI **Technical Changes:** - Centralized styling logic in shared components - Removed hardcoded widths for better responsiveness - Fixed inconsistent text colors (foreground vs muted-foreground) - Standardized gap spacing (2, 3, 4 units) - All changes pass TypeScript and ESLint checks --- .../Settings/AccessTokenSection.tsx | 128 ++++++------ .../components/Settings/InstanceSection.tsx | 192 +++++++++--------- web/src/components/Settings/MemberSection.tsx | 143 +++++++------ .../Settings/MemoRelatedSettings.tsx | 192 +++++++++--------- .../components/Settings/MyAccountSection.tsx | 68 ++++--- .../Settings/PreferencesSection.tsx | 75 ++++--- web/src/components/Settings/SSOSection.tsx | 95 +++++---- web/src/components/Settings/SettingGroup.tsx | 34 ++++ web/src/components/Settings/SettingRow.tsx | 45 ++++ .../components/Settings/SettingSection.tsx | 35 ++++ web/src/components/Settings/SettingTable.tsx | 69 +++++++ .../components/Settings/StorageSection.tsx | 153 +++++++------- .../Settings/UserSessionsSection.tsx | 178 ++++++++-------- .../components/Settings/WebhookSection.tsx | 102 ++++------ 14 files changed, 829 insertions(+), 680 deletions(-) create mode 100644 web/src/components/Settings/SettingGroup.tsx create mode 100644 web/src/components/Settings/SettingRow.tsx create mode 100644 web/src/components/Settings/SettingSection.tsx create mode 100644 web/src/components/Settings/SettingTable.tsx diff --git a/web/src/components/Settings/AccessTokenSection.tsx b/web/src/components/Settings/AccessTokenSection.tsx index e4cf3f6da..f3191d2a6 100644 --- a/web/src/components/Settings/AccessTokenSection.tsx +++ b/web/src/components/Settings/AccessTokenSection.tsx @@ -1,5 +1,5 @@ import copy from "copy-to-clipboard"; -import { ClipboardIcon, TrashIcon } from "lucide-react"; +import { ClipboardIcon, PlusIcon, TrashIcon } from "lucide-react"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import ConfirmDialog from "@/components/ConfirmDialog"; @@ -10,6 +10,7 @@ import { useDialog } from "@/hooks/useDialog"; import { UserAccessToken } from "@/types/proto/api/v1/user_service"; import { useTranslate } from "@/utils/i18n"; import CreateAccessTokenDialog from "../CreateAccessTokenDialog"; +import SettingTable from "./SettingTable"; const listAccessTokens = async (parent: string) => { const { accessTokens } = await userServiceClient.listUserAccessTokens({ parent }); @@ -63,79 +64,64 @@ const AccessTokenSection = () => { }; return ( -
-
-
-
-

- {t("setting.access-token-section.title")} -

-

{t("setting.access-token-section.description")}

-
-
- -
-
-
-
-
- - - - - - - - - - - - {userAccessTokens.map((userAccessToken) => ( - - - - - - - - ))} - -
- {t("setting.access-token-section.token")} - - {t("common.description")} - - {t("setting.access-token-section.create-dialog.created-at")} - - {t("setting.access-token-section.create-dialog.expires-at")} - - {t("common.delete")} -
- {getFormatedAccessToken(userAccessToken.accessToken)} - - {userAccessToken.description} - {userAccessToken.issuedAt?.toLocaleString()} - - {userAccessToken.expiresAt?.toLocaleString() ?? t("setting.access-token-section.create-dialog.duration-never")} - - -
-
-
+
+
+
+

{t("setting.access-token-section.title")}

+

{t("setting.access-token-section.description")}

+
+ ( +
+ {getFormatedAccessToken(token.accessToken)} + +
+ ), + }, + { + key: "description", + header: t("common.description"), + render: (_, token: UserAccessToken) => {token.description}, + }, + { + key: "issuedAt", + header: t("setting.access-token-section.create-dialog.created-at"), + render: (_, token: UserAccessToken) => token.issuedAt?.toLocaleString(), + }, + { + key: "expiresAt", + header: t("setting.access-token-section.create-dialog.expires-at"), + render: (_, token: UserAccessToken) => + token.expiresAt?.toLocaleString() ?? t("setting.access-token-section.create-dialog.duration-never"), + }, + { + key: "actions", + header: "", + className: "text-right", + render: (_, token: UserAccessToken) => ( + + ), + }, + ]} + data={userAccessTokens} + emptyMessage="No access tokens found" + getRowKey={(token) => token.name} + /> + {/* Create Access Token Dialog */} { const t = useTranslate(); @@ -67,99 +69,99 @@ const InstanceSection = observer(() => { }; return ( -
-

{t("common.basic")}

-
-
- {t("setting.system-section.server-name")}:{" "} - {instanceGeneralSetting.customProfile?.title || "Memos"} -
- -
- -

{t("setting.system-section.title")}

-
- Theme - updatePartialSetting({ theme: value })} - className="min-w-fit" - /> -
-
- {t("setting.system-section.additional-style")} -
-