mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-01 03:46:25 +02:00
refactor: enhance ApiKeyContent and MobileSidebar components with improved styling and event handling for better user experience
This commit is contained in:
parent
863ba6865c
commit
f14efa18b3
2 changed files with 96 additions and 40 deletions
|
|
@ -1,16 +1,30 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Check, Copy, Shield } from "lucide-react";
|
import { Check, Copy, Info } from "lucide-react";
|
||||||
import { AnimatePresence, motion } from "motion/react";
|
import { AnimatePresence, motion } from "motion/react";
|
||||||
|
import { useCallback, useRef, useState } from "react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { useApiKey } from "@/hooks/use-api-key";
|
import { useApiKey } from "@/hooks/use-api-key";
|
||||||
|
import { copyToClipboard as copyToClipboardUtil } from "@/lib/utils";
|
||||||
|
|
||||||
export function ApiKeyContent() {
|
export function ApiKeyContent() {
|
||||||
const t = useTranslations("userSettings");
|
const t = useTranslations("userSettings");
|
||||||
const { apiKey, isLoading, copied, copyToClipboard } = useApiKey();
|
const { apiKey, isLoading, copied, copyToClipboard } = useApiKey();
|
||||||
|
const [copiedUsage, setCopiedUsage] = useState(false);
|
||||||
|
const usageCopyTimeoutRef = useRef<ReturnType<typeof setTimeout>>(null);
|
||||||
|
|
||||||
|
const copyUsageToClipboard = useCallback(async () => {
|
||||||
|
const text = `Authorization: Bearer ${apiKey || "YOUR_API_KEY"}`;
|
||||||
|
const success = await copyToClipboardUtil(text);
|
||||||
|
if (success) {
|
||||||
|
setCopiedUsage(true);
|
||||||
|
if (usageCopyTimeoutRef.current) clearTimeout(usageCopyTimeoutRef.current);
|
||||||
|
usageCopyTimeoutRef.current = setTimeout(() => setCopiedUsage(false), 2000);
|
||||||
|
}
|
||||||
|
}, [apiKey]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
|
|
@ -22,49 +36,70 @@ export function ApiKeyContent() {
|
||||||
transition={{ duration: 0.35, ease: [0.4, 0, 0.2, 1] }}
|
transition={{ duration: 0.35, ease: [0.4, 0, 0.2, 1] }}
|
||||||
className="space-y-6"
|
className="space-y-6"
|
||||||
>
|
>
|
||||||
<Alert>
|
<Alert className="border-border/60 bg-muted/30 text-muted-foreground">
|
||||||
<Shield className="h-4 w-4" />
|
<Info className="h-4 w-4 text-muted-foreground" />
|
||||||
<AlertTitle>{t("api_key_warning_title")}</AlertTitle>
|
<AlertTitle className="text-muted-foreground">{t("api_key_warning_title")}</AlertTitle>
|
||||||
<AlertDescription>{t("api_key_warning_description")}</AlertDescription>
|
<AlertDescription className="text-muted-foreground/60">{t("api_key_warning_description")}</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
<div className="rounded-lg border bg-card p-6">
|
<div className="rounded-lg border border-border/60 bg-card p-6">
|
||||||
<h3 className="mb-4 font-medium">{t("your_api_key")}</h3>
|
<h3 className="mb-4 text-sm font-semibold tracking-tight">{t("your_api_key")}</h3>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="h-12 w-full animate-pulse rounded-md bg-muted" />
|
<div className="h-12 w-full animate-pulse rounded-md border border-border/60 bg-muted/30" />
|
||||||
) : apiKey ? (
|
) : apiKey ? (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-2.5 py-1.5">
|
||||||
<div className="flex-1 overflow-x-auto rounded-md bg-muted p-3 font-mono text-sm">
|
<div className="min-w-0 flex-1 overflow-x-auto scrollbar-hide">
|
||||||
|
<p className="font-mono text-[10px] text-muted-foreground whitespace-nowrap select-all cursor-text">
|
||||||
{apiKey}
|
{apiKey}
|
||||||
</div>
|
</p>
|
||||||
<TooltipProvider>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={copyToClipboard}
|
|
||||||
className="shrink-0"
|
|
||||||
>
|
|
||||||
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>{copied ? t("copied") : t("copy")}</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
<TooltipProvider>
|
||||||
<p className="text-center text-muted-foreground">{t("no_api_key")}</p>
|
<Tooltip>
|
||||||
)}
|
<TooltipTrigger asChild>
|
||||||
</div>
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={copyToClipboard}
|
||||||
|
className="h-6 w-6 shrink-0 text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
{copied ? <Check className="h-3 w-3 text-green-500" /> : <Copy className="h-3 w-3" />}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>{copied ? t("copied") : t("copy")}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-center text-muted-foreground/60">{t("no_api_key")}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="rounded-lg border bg-card p-6">
|
<div className="rounded-lg border border-border/60 bg-card p-6">
|
||||||
<h3 className="mb-2 font-medium">{t("usage_title")}</h3>
|
<h3 className="mb-2 text-sm font-semibold tracking-tight">{t("usage_title")}</h3>
|
||||||
<p className="mb-4 text-sm text-muted-foreground">{t("usage_description")}</p>
|
<p className="mb-4 text-[11px] text-muted-foreground/60">{t("usage_description")}</p>
|
||||||
<pre className="overflow-x-auto rounded-md bg-muted p-3 text-sm">
|
<div className="flex items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-2.5 py-1.5">
|
||||||
|
<div className="min-w-0 flex-1 overflow-x-auto scrollbar-hide">
|
||||||
|
<pre className="font-mono text-[10px] text-muted-foreground whitespace-nowrap select-all cursor-text">
|
||||||
<code>Authorization: Bearer {apiKey || "YOUR_API_KEY"}</code>
|
<code>Authorization: Bearer {apiKey || "YOUR_API_KEY"}</code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={copyUsageToClipboard}
|
||||||
|
className="h-6 w-6 shrink-0 text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
{copiedUsage ? <Check className="h-3 w-3 text-green-500" /> : <Copy className="h-3 w-3" />}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>{copiedUsage ? t("copied") : t("copy")}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -166,9 +166,30 @@ export function MobileSidebar({
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
user={user}
|
user={user}
|
||||||
onSettings={onSettings}
|
onSettings={
|
||||||
onManageMembers={onManageMembers}
|
onSettings
|
||||||
onUserSettings={onUserSettings}
|
? () => {
|
||||||
|
onOpenChange(false);
|
||||||
|
onSettings();
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onManageMembers={
|
||||||
|
onManageMembers
|
||||||
|
? () => {
|
||||||
|
onOpenChange(false);
|
||||||
|
onManageMembers();
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onUserSettings={
|
||||||
|
onUserSettings
|
||||||
|
? () => {
|
||||||
|
onOpenChange(false);
|
||||||
|
onUserSettings();
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
onLogout={onLogout}
|
onLogout={onLogout}
|
||||||
pageUsage={pageUsage}
|
pageUsage={pageUsage}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue