mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 02:11:48 +00:00
chore: more components
This commit is contained in:
parent
e116957a63
commit
a9369fc193
3 changed files with 56 additions and 105 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import { ExternalLink, Copy, X, Check, Loader2 } from "lucide-react";
|
||||
import { Button, H2 } from "@nous-research/ui";
|
||||
import { ExternalLink, X, Check, Loader2 } from "lucide-react";
|
||||
import { Button, CopyButton, H2 } from "@nous-research/ui";
|
||||
import { api, type OAuthProvider, type OAuthStartResponse } from "@/lib/api";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
|
@ -25,14 +25,12 @@ export function OAuthLoginModal({
|
|||
provider,
|
||||
onClose,
|
||||
onSuccess,
|
||||
onError,
|
||||
}: Props) {
|
||||
const [phase, setPhase] = useState<Phase>("starting");
|
||||
const [start, setStart] = useState<OAuthStartResponse | null>(null);
|
||||
const [pkceCode, setPkceCode] = useState("");
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
||||
const [secondsLeft, setSecondsLeft] = useState<number | null>(null);
|
||||
const [codeCopied, setCodeCopied] = useState(false);
|
||||
const isMounted = useRef(true);
|
||||
const pollTimer = useRef<number | null>(null);
|
||||
const { t } = useI18n();
|
||||
|
|
@ -153,16 +151,6 @@ export function OAuthLoginModal({
|
|||
onClose();
|
||||
};
|
||||
|
||||
const handleCopyUserCode = async (code: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(code);
|
||||
setCodeCopied(true);
|
||||
window.setTimeout(() => isMounted.current && setCodeCopied(false), 1500);
|
||||
} catch {
|
||||
onError("Clipboard write failed");
|
||||
}
|
||||
};
|
||||
|
||||
const handleBackdrop = (e: React.MouseEvent) => {
|
||||
if (e.target === e.currentTarget) handleClose();
|
||||
};
|
||||
|
|
@ -286,26 +274,16 @@ export function OAuthLoginModal({
|
|||
).user_code
|
||||
}
|
||||
</code>
|
||||
<Button
|
||||
outlined
|
||||
onClick={() =>
|
||||
handleCopyUserCode(
|
||||
(
|
||||
start as Extract<
|
||||
OAuthStartResponse,
|
||||
{ flow: "device_code" }
|
||||
>
|
||||
).user_code,
|
||||
)
|
||||
<CopyButton
|
||||
text={
|
||||
(
|
||||
start as Extract<
|
||||
OAuthStartResponse,
|
||||
{ flow: "device_code" }
|
||||
>
|
||||
).user_code
|
||||
}
|
||||
className="!p-2 aspect-square"
|
||||
>
|
||||
{codeCopied ? (
|
||||
<Check className="h-3.5 w-3.5" />
|
||||
) : (
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
)}
|
||||
</Button>
|
||||
/>
|
||||
</div>
|
||||
<a
|
||||
href={
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect, useState, useCallback, useRef } from "react";
|
||||
import { ShieldCheck, ShieldOff, Copy, ExternalLink, RefreshCw, LogOut, Terminal, LogIn } from "lucide-react";
|
||||
import { ShieldCheck, ShieldOff, ExternalLink, RefreshCw, LogOut, Terminal, LogIn } from "lucide-react";
|
||||
import { api, type OAuthProvider } from "@/lib/api";
|
||||
import { Button } from "@nous-research/ui";
|
||||
import { Button, CopyButton } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { OAuthLoginModal } from "@/components/OAuthLoginModal";
|
||||
|
|
@ -35,7 +35,6 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
const [providers, setProviders] = useState<OAuthProvider[] | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [busyId, setBusyId] = useState<string | null>(null);
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null);
|
||||
const [loginFor, setLoginFor] = useState<OAuthProvider | null>(null);
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
@ -55,17 +54,6 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
refresh();
|
||||
}, [refresh]);
|
||||
|
||||
const handleCopy = async (provider: OAuthProvider) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(provider.cli_command);
|
||||
setCopiedId(provider.id);
|
||||
onSuccess?.(`Copied: ${provider.cli_command}`);
|
||||
setTimeout(() => setCopiedId((v) => (v === provider.id ? null : v)), 1500);
|
||||
} catch {
|
||||
onError?.("Clipboard write failed — copy the command manually");
|
||||
}
|
||||
};
|
||||
|
||||
const handleDisconnect = async (provider: OAuthProvider) => {
|
||||
if (!confirm(`${t.oauth.disconnect} ${provider.name}?`)) {
|
||||
return;
|
||||
|
|
@ -206,14 +194,11 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
</Button>
|
||||
)}
|
||||
{!p.status.logged_in && (
|
||||
<Button
|
||||
outlined
|
||||
onClick={() => handleCopy(p)}
|
||||
title={t.oauth.copyCliCommand}
|
||||
prefix={copiedId === p.id ? undefined : <Copy />}
|
||||
>
|
||||
{copiedId === p.id ? t.oauth.copied : t.oauth.cli}
|
||||
</Button>
|
||||
<CopyButton
|
||||
text={p.cli_command}
|
||||
label={t.oauth.cli}
|
||||
copiedLabel={t.oauth.copied}
|
||||
/>
|
||||
)}
|
||||
{p.status.logged_in && p.flow !== "external" && (
|
||||
<Button
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue