feat: port the demo redesign with Manage and Settings tabs

This commit is contained in:
LukeGus committed 2026-10-05 16:23:21 -05:00
1 parent f8151cb885
commit 35c954b79a
128 files changed
+13262 -8143

No files matched your search

+75 -43
View File
@@ -1,4 +1,6 @@
import type React from "react";
import { useRef, useState } from "react";
import { EditorPane, EditorSection } from "@/manage/EditorPane";
import { PluginComponent } from "@/plugin-host/component-registry";
import { useTranslation } from "react-i18next";
import { copyToClipboard } from "@/lib/clipboard";
@@ -23,7 +25,7 @@ import { FolderPathPicker } from "./FolderPathPicker";
export function CredentialEditorView({
credential,
activeTab,
banner,
onBack,
onSave,
adminTargetUserId,
@@ -31,7 +33,8 @@ export function CredentialEditorView({
saveAsNewHost,
}: {
credential: Credential | null;
activeTab: string;
/** Shown above the form. */
banner?: React.ReactNode;
onBack: () => void;
onSave: (
saved: Record<string, unknown>,
@@ -170,9 +173,73 @@ export function CredentialEditorView({
}
};
const nameMissing = !credForm.name.trim();
const bands = [
{
id: "credential",
label: t("manage.bandCredential"),
items: [
{
id: "general",
label: t("hosts.basicInformation"),
icon: <Info className="size-3.5" />,
error: nameMissing,
},
{
id: "auth",
label: t("hosts.authDetailsSection"),
icon: <Lock className="size-3.5" />,
},
],
},
];
return (
<div className="flex flex-col gap-3">
{activeTab === "general" && (
<EditorPane
bands={bands}
banner={banner}
errorCount={nameMissing ? 1 : 0}
footer={
<>
<Button
variant="ghost"
size="sm"
onClick={onBack}
disabled={saving || savingAsNew}
>
{t("hosts.cancelBtn")}
</Button>
{saveAsNewHost && credential && !adminTargetUserId && (
<Button
variant="outline"
size="sm"
className="px-4"
onClick={handleSaveAsNew}
disabled={saving || savingAsNew || nameMissing}
title={t("hosts.saveCredentialAsNewDesc")}
>
{savingAsNew
? t("hosts.savingBtn")
: t("hosts.saveCredentialAsNewBtn")}
</Button>
)}
<Button
variant="outline"
size="sm"
className="border-accent-brand/40 text-accent-brand hover:bg-accent-brand/10 hover:text-accent-brand px-6"
onClick={handleSave}
disabled={saving || savingAsNew || nameMissing}
>
{saving
? t("hosts.savingBtn")
: credential
? t("hosts.updateCredentialBtn")
: t("hosts.addCredentialBtn")}
</Button>
</>
}
>
<EditorSection id="general" showHeading={false}>
<SectionCard
title={t("hosts.basicInformation")}
icon={<Info className="size-3.5" />}
@@ -265,9 +332,9 @@ export function CredentialEditorView({
</div>
</div>
</SectionCard>
)}
</EditorSection>
{activeTab === "auth" && (
<EditorSection id="auth" showHeading={false}>
<SectionCard
title={t("hosts.authDetailsSection")}
icon={<Lock className="size-3.5" />}
@@ -544,42 +611,7 @@ export function CredentialEditorView({
</div>
</div>
</SectionCard>
)}
<div className="flex justify-end gap-3 mt-3">
<Button
variant="ghost"
onClick={onBack}
disabled={saving || savingAsNew}
>
{t("hosts.cancelBtn")}
</Button>
{saveAsNewHost && credential && !adminTargetUserId && (
<Button
variant="outline"
className="px-6"
onClick={handleSaveAsNew}
disabled={saving || savingAsNew}
title={t("hosts.saveCredentialAsNewDesc")}
>
{savingAsNew
? t("hosts.savingBtn")
: t("hosts.saveCredentialAsNewBtn")}
</Button>
)}
<Button
variant="outline"
className="border-accent-brand/40 text-accent-brand hover:bg-accent-brand/10 hover:text-accent-brand px-8"
onClick={handleSave}
disabled={saving || savingAsNew}
>
{saving
? t("hosts.savingBtn")
: credential
? t("hosts.updateCredentialBtn")
: t("hosts.addCredentialBtn")}
</Button>
</div>
</div>
</EditorSection>
</EditorPane>
);
}