mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-06 22:12:12 +02:00
Delete old pages, fix duplicate translations, rename to 'Manage Members'
This commit is contained in:
parent
814122d087
commit
3dff7487b1
6 changed files with 1 additions and 274 deletions
|
|
@ -1,185 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import { IconCheck, IconCopy, IconKey } from "@tabler/icons-react";
|
|
||||||
import { ArrowLeft } from "lucide-react";
|
|
||||||
import { AnimatePresence, motion } from "motion/react";
|
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
|
||||||
import { useApiKey } from "@/hooks/use-api-key";
|
|
||||||
|
|
||||||
const fadeIn = {
|
|
||||||
hidden: { opacity: 0 },
|
|
||||||
visible: { opacity: 1, transition: { duration: 0.4 } },
|
|
||||||
};
|
|
||||||
|
|
||||||
const staggerContainer = {
|
|
||||||
hidden: { opacity: 0 },
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
staggerChildren: 0.1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const ApiKeyClient = () => {
|
|
||||||
const { apiKey, isLoading, copied, copyToClipboard } = useApiKey();
|
|
||||||
const router = useRouter();
|
|
||||||
return (
|
|
||||||
<div className="flex justify-center w-full min-h-screen py-10 px-4">
|
|
||||||
<motion.div
|
|
||||||
className="w-full max-w-3xl"
|
|
||||||
initial="hidden"
|
|
||||||
animate="visible"
|
|
||||||
variants={staggerContainer}
|
|
||||||
>
|
|
||||||
<motion.div className="mb-8 text-center" variants={fadeIn}>
|
|
||||||
<h1 className="text-3xl font-bold tracking-tight">API Key</h1>
|
|
||||||
<p className="text-muted-foreground mt-2">
|
|
||||||
Your API key for authenticating with the SurfSense API.
|
|
||||||
</p>
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
<motion.div variants={fadeIn}>
|
|
||||||
<Alert className="mb-8">
|
|
||||||
<IconKey className="h-4 w-4" />
|
|
||||||
<AlertTitle>Important</AlertTitle>
|
|
||||||
<AlertDescription>
|
|
||||||
Your API key grants full access to your account. Never share it publicly or with
|
|
||||||
unauthorized users.
|
|
||||||
</AlertDescription>
|
|
||||||
</Alert>
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
<motion.div variants={fadeIn}>
|
|
||||||
<Card>
|
|
||||||
<CardHeader className="text-center">
|
|
||||||
<CardTitle>Your API Key</CardTitle>
|
|
||||||
<CardDescription>Use this key to authenticate your API requests.</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<AnimatePresence mode="wait">
|
|
||||||
{isLoading ? (
|
|
||||||
<motion.div
|
|
||||||
key="loading"
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
exit={{ opacity: 0 }}
|
|
||||||
className="h-10 w-full bg-muted animate-pulse rounded-md"
|
|
||||||
/>
|
|
||||||
) : apiKey ? (
|
|
||||||
<motion.div
|
|
||||||
key="api-key"
|
|
||||||
initial={{ opacity: 0, y: 10 }}
|
|
||||||
animate={{ opacity: 1, y: 0 }}
|
|
||||||
exit={{ opacity: 0, y: -10 }}
|
|
||||||
transition={{ type: "spring", stiffness: 500, damping: 30 }}
|
|
||||||
className="flex items-center space-x-2"
|
|
||||||
>
|
|
||||||
<div className="bg-muted p-3 rounded-md flex-1 font-mono text-sm overflow-x-auto whitespace-nowrap">
|
|
||||||
<motion.div
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
transition={{ duration: 0.5 }}
|
|
||||||
>
|
|
||||||
{apiKey}
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
<TooltipProvider>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={copyToClipboard}
|
|
||||||
className="flex-shrink-0"
|
|
||||||
>
|
|
||||||
<motion.div
|
|
||||||
whileTap={{ scale: 0.9 }}
|
|
||||||
animate={copied ? { scale: [1, 1.2, 1] } : {}}
|
|
||||||
transition={{ duration: 0.2 }}
|
|
||||||
>
|
|
||||||
{copied ? (
|
|
||||||
<IconCheck className="h-4 w-4" />
|
|
||||||
) : (
|
|
||||||
<IconCopy className="h-4 w-4" />
|
|
||||||
)}
|
|
||||||
</motion.div>
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>{copied ? "Copied!" : "Copy to clipboard"}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
</motion.div>
|
|
||||||
) : (
|
|
||||||
<motion.div
|
|
||||||
key="no-key"
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
exit={{ opacity: 0 }}
|
|
||||||
className="text-muted-foreground text-center"
|
|
||||||
>
|
|
||||||
No API key found.
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
<motion.div
|
|
||||||
className="mt-8"
|
|
||||||
variants={fadeIn}
|
|
||||||
initial={{ opacity: 0, y: 20 }}
|
|
||||||
animate={{ opacity: 1, y: 0 }}
|
|
||||||
transition={{ delay: 0.3 }}
|
|
||||||
>
|
|
||||||
<h2 className="text-xl font-semibold mb-4 text-center">How to use your API key</h2>
|
|
||||||
<Card>
|
|
||||||
<CardContent className="pt-6">
|
|
||||||
<motion.div
|
|
||||||
className="space-y-4"
|
|
||||||
initial="hidden"
|
|
||||||
animate="visible"
|
|
||||||
variants={staggerContainer}
|
|
||||||
>
|
|
||||||
<motion.div variants={fadeIn}>
|
|
||||||
<h3 className="font-medium mb-2 text-center">Authentication</h3>
|
|
||||||
<p className="text-sm text-muted-foreground text-center">
|
|
||||||
Include your API key in the Authorization header of your requests:
|
|
||||||
</p>
|
|
||||||
<motion.pre
|
|
||||||
className="bg-muted p-3 rounded-md mt-2 overflow-x-auto"
|
|
||||||
whileHover={{ scale: 1.01 }}
|
|
||||||
transition={{ type: "spring", stiffness: 400, damping: 10 }}
|
|
||||||
>
|
|
||||||
<code className="text-xs">
|
|
||||||
Authorization: Bearer {apiKey || "YOUR_API_KEY"}
|
|
||||||
</code>
|
|
||||||
</motion.pre>
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => router.push("/dashboard")}
|
|
||||||
className="flex items-center justify-center h-10 w-10 rounded-lg bg-primary/10 hover:bg-primary/30 transition-colors"
|
|
||||||
aria-label="Back to Dashboard"
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<ArrowLeft className="h-5 w-5 text-primary" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ApiKeyClient;
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import dynamic from "next/dynamic";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
|
|
||||||
// Loading component with animation
|
|
||||||
const LoadingComponent = () => (
|
|
||||||
<div className="flex flex-col justify-center items-center min-h-screen">
|
|
||||||
<div className="w-16 h-16 border-4 border-primary border-t-transparent rounded-full animate-spin mb-4"></div>
|
|
||||||
<p className="text-muted-foreground">Loading API Key Management...</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
// Dynamically import the ApiKeyClient component
|
|
||||||
const ApiKeyClient = dynamic(() => import("./api-key-client"), {
|
|
||||||
ssr: false,
|
|
||||||
loading: () => <LoadingComponent />,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function ClientWrapper() {
|
|
||||||
const [isMounted, setIsMounted] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsMounted(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!isMounted) {
|
|
||||||
return <LoadingComponent />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ApiKeyClient />;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import ClientWrapper from "./client-wrapper";
|
|
||||||
|
|
||||||
export default function ApiKeyPage() {
|
|
||||||
return <ClientWrapper />;
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import { useAtomValue } from "jotai";
|
|
||||||
import { motion } from "motion/react";
|
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { createSearchSpaceMutationAtom } from "@/atoms/search-spaces/search-space-mutation.atoms";
|
|
||||||
import { SearchSpaceForm } from "@/components/search-space-form";
|
|
||||||
import { trackSearchSpaceCreated } from "@/lib/posthog/events";
|
|
||||||
|
|
||||||
export default function SearchSpacesPage() {
|
|
||||||
const router = useRouter();
|
|
||||||
const { mutateAsync: createSearchSpace } = useAtomValue(createSearchSpaceMutationAtom);
|
|
||||||
|
|
||||||
const handleCreateSearchSpace = async (data: { name: string; description?: string }) => {
|
|
||||||
const result = await createSearchSpace({
|
|
||||||
name: data.name,
|
|
||||||
description: data.description || "",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Track search space creation
|
|
||||||
trackSearchSpaceCreated(result.id, data.name);
|
|
||||||
|
|
||||||
// Redirect to the newly created search space's onboarding
|
|
||||||
router.push(`/dashboard/${result.id}/onboard`);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
className="mx-auto max-w-5xl px-4 py-6 lg:py-10"
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
transition={{ duration: 0.5 }}
|
|
||||||
>
|
|
||||||
<div className="mx-auto max-w-5xl">
|
|
||||||
<SearchSpaceForm onSubmit={handleCreateSearchSpace} />
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -666,13 +666,9 @@
|
||||||
"no_archived_chats": "No archived chats",
|
"no_archived_chats": "No archived chats",
|
||||||
"error_archiving_chat": "Failed to archive chat",
|
"error_archiving_chat": "Failed to archive chat",
|
||||||
"new_chat": "New chat",
|
"new_chat": "New chat",
|
||||||
"select_workspace": "Select Workspace",
|
|
||||||
"select_search_space": "Select Search Space",
|
"select_search_space": "Select Search Space",
|
||||||
"invite_members": "Invite members",
|
|
||||||
"manage_members": "Manage members",
|
"manage_members": "Manage members",
|
||||||
"workspace_settings": "Workspace settings",
|
"search_space_settings": "Search Space settings",
|
||||||
"search_space_settings": "Search space settings",
|
|
||||||
"see_all_workspaces": "See all search spaces",
|
|
||||||
"see_all_search_spaces": "See all search spaces",
|
"see_all_search_spaces": "See all search spaces",
|
||||||
"expand_sidebar": "Expand sidebar",
|
"expand_sidebar": "Expand sidebar",
|
||||||
"collapse_sidebar": "Collapse sidebar",
|
"collapse_sidebar": "Collapse sidebar",
|
||||||
|
|
|
||||||
|
|
@ -660,13 +660,9 @@
|
||||||
"view_all_notes": "查看所有笔记",
|
"view_all_notes": "查看所有笔记",
|
||||||
"add_note": "添加笔记",
|
"add_note": "添加笔记",
|
||||||
"new_chat": "新对话",
|
"new_chat": "新对话",
|
||||||
"select_workspace": "选择工作空间",
|
|
||||||
"select_search_space": "选择搜索空间",
|
"select_search_space": "选择搜索空间",
|
||||||
"invite_members": "邀请成员",
|
|
||||||
"manage_members": "管理成员",
|
"manage_members": "管理成员",
|
||||||
"workspace_settings": "工作空间设置",
|
|
||||||
"search_space_settings": "搜索空间设置",
|
"search_space_settings": "搜索空间设置",
|
||||||
"see_all_workspaces": "查看所有搜索空间",
|
|
||||||
"see_all_search_spaces": "查看所有搜索空间",
|
"see_all_search_spaces": "查看所有搜索空间",
|
||||||
"expand_sidebar": "展开侧边栏",
|
"expand_sidebar": "展开侧边栏",
|
||||||
"collapse_sidebar": "收起侧边栏",
|
"collapse_sidebar": "收起侧边栏",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue