mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-08 03:08:21 +00:00
feat: app improvements (#454)
This commit is contained in:
parent
0ca737f364
commit
cdfb942fa8
10 changed files with 86 additions and 235 deletions
|
|
@ -7,7 +7,7 @@ import { ChatMessages } from "@/components/views/chat/chat-messages"
|
|||
|
||||
export default function ChatPage() {
|
||||
const params = useParams()
|
||||
const { setCurrentChatId, getCurrentChat } = usePersistentChat()
|
||||
const { setCurrentChatId } = usePersistentChat()
|
||||
|
||||
const chatId = params.id as string
|
||||
|
||||
|
|
@ -17,17 +17,9 @@ export default function ChatPage() {
|
|||
}
|
||||
}, [chatId, setCurrentChatId])
|
||||
|
||||
const currentChat = getCurrentChat()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="flex flex-col h-[93vh]">
|
||||
<div className="flex justify-center w-full">
|
||||
<h1 className="text-lg font-semibold flex-1 truncate text-center">
|
||||
{currentChat?.title || "New Chat"}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex justify-center min-h-0 w-full px-4">
|
||||
<div className="flex flex-col min-h-0 w-full max-w-4xl">
|
||||
<ChatMessages />
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ export function MCPForm() {
|
|||
<Button
|
||||
variant="link"
|
||||
size="lg"
|
||||
className="text-black/40 font-medium! text-lg underline w-fit px-0! cursor-pointer"
|
||||
className="text-white not-odd:font-medium! text-lg underline w-fit px-0! cursor-pointer"
|
||||
onClick={nextStep}
|
||||
>
|
||||
Continue
|
||||
|
|
@ -238,7 +238,7 @@ export function MCPForm() {
|
|||
<Button
|
||||
variant="link"
|
||||
size="lg"
|
||||
className="text-black/40 font-medium! text-lg underline w-fit px-0! cursor-pointer"
|
||||
className="text-white font-medium! text-lg underline w-fit px-0! cursor-pointer"
|
||||
onClick={nextStep}
|
||||
>
|
||||
Skip For Now
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ export function OnboardingBackground({ children }: OnboardingBackgroundProps) {
|
|||
backgroundPosition: "bottom",
|
||||
backgroundRepeat: "no-repeat",
|
||||
transform: `scale(${zoomScale})`,
|
||||
transformOrigin: "center bottom",
|
||||
}}
|
||||
/>
|
||||
<div className="relative z-10 w-full max-w-4xl mx-auto">{children}</div>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export function ChatInput() {
|
|||
className="w-full text-foreground placeholder-muted-foreground rounded-md outline-none resize-none text-base leading-relaxed px-6 py-4 bg-transparent"
|
||||
rows={2}
|
||||
/>
|
||||
<div className="flex items-center gap-2 w-full justify-between bg-accent py-2 px-3 rounded-b-[14px]">
|
||||
<div className="flex items-center gap-2 w-full justify-between py-2 px-3 rounded-b-[14px]">
|
||||
<ProjectSelector />
|
||||
<Button
|
||||
onClick={handleSend}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
DialogTitle,
|
||||
} from "@repo/ui/components/dialog"
|
||||
import { Input } from "@repo/ui/components/input"
|
||||
import { Label } from "@repo/ui/components/label"
|
||||
import { Loader2 } from "lucide-react"
|
||||
import { AnimatePresence, motion } from "motion/react"
|
||||
import { useState } from "react"
|
||||
|
|
@ -47,7 +46,7 @@ export function CreateProjectDialog({
|
|||
<AnimatePresence>
|
||||
{open && (
|
||||
<Dialog onOpenChange={onOpenChange} open={open}>
|
||||
<DialogContent className="sm:max-w-2xl bg-[#0f1419] backdrop-blur-xl border-white/10 text-white">
|
||||
<DialogContent className="sm:max-w-2xl backdrop-blur-xl">
|
||||
<motion.div
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
|
|
@ -55,7 +54,7 @@ export function CreateProjectDialog({
|
|||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Create New Project</DialogTitle>
|
||||
<DialogDescription className="text-white/60">
|
||||
<DialogDescription>
|
||||
Give your project a unique name
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
|
@ -66,9 +65,7 @@ export function CreateProjectDialog({
|
|||
initial={{ opacity: 0, y: 10 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
<Label htmlFor="projectName">Project Name</Label>
|
||||
<Input
|
||||
className="bg-white/5 border-white/10 text-white"
|
||||
id="projectName"
|
||||
onChange={(e) => setProjectName(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
|
|
@ -79,47 +76,31 @@ export function CreateProjectDialog({
|
|||
placeholder="My Awesome Project"
|
||||
value={projectName}
|
||||
/>
|
||||
<p className="text-xs text-white/50">
|
||||
<p className="text-xs">
|
||||
This will help you organize your memories
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
<Button onClick={handleClose} type="button" variant="outline">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
disabled={
|
||||
createProjectMutation.isPending || !projectName.trim()
|
||||
}
|
||||
onClick={handleCreate}
|
||||
type="button"
|
||||
>
|
||||
<Button
|
||||
className="bg-white/5 hover:bg-white/10 border-white/10 text-white"
|
||||
onClick={handleClose}
|
||||
type="button"
|
||||
variant="outline"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Button
|
||||
className="bg-white/10 hover:bg-white/20 text-white border-white/20"
|
||||
disabled={
|
||||
createProjectMutation.isPending || !projectName.trim()
|
||||
}
|
||||
onClick={handleCreate}
|
||||
type="button"
|
||||
>
|
||||
{createProjectMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin mr-2" />
|
||||
Creating...
|
||||
</>
|
||||
) : (
|
||||
"Create Project"
|
||||
)}
|
||||
</Button>
|
||||
</motion.div>
|
||||
{createProjectMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin mr-2" />
|
||||
Creating...
|
||||
</>
|
||||
) : (
|
||||
"Create Project"
|
||||
)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</motion.div>
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ import {
|
|||
Plus,
|
||||
SunIcon,
|
||||
MonitorIcon,
|
||||
Network,
|
||||
User,
|
||||
CreditCard,
|
||||
Chrome,
|
||||
LogOut,
|
||||
WaypointsIcon,
|
||||
Gauge,
|
||||
} from "lucide-react"
|
||||
import {
|
||||
DropdownMenuContent,
|
||||
|
|
@ -25,17 +26,19 @@ import { useAuth } from "@lib/auth-context"
|
|||
import { ConnectAIModal } from "./connect-ai-modal"
|
||||
import { useTheme } from "next-themes"
|
||||
import { cn } from "@lib/utils"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
import { MCPIcon } from "./menu"
|
||||
import { authClient } from "@lib/auth"
|
||||
import { analytics } from "@/lib/analytics"
|
||||
import { useGraphModal } from "@/stores"
|
||||
import { useGraphModal, usePersistentChat } from "@/stores"
|
||||
|
||||
export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
||||
const { user } = useAuth()
|
||||
const { theme, setTheme } = useTheme()
|
||||
const router = useRouter()
|
||||
const { setIsOpen: setGraphModalOpen } = useGraphModal()
|
||||
const { getCurrentChat } = usePersistentChat()
|
||||
const pathname = usePathname()
|
||||
|
||||
const handleSignOut = () => {
|
||||
analytics.userSignedOut()
|
||||
|
|
@ -46,20 +49,31 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
|||
return (
|
||||
<div className="flex items-center justify-between w-full p-3 md:p-4">
|
||||
<div className="flex items-center gap-2 md:gap-3 justify-between w-full">
|
||||
<Link
|
||||
className="pointer-events-auto"
|
||||
href={
|
||||
process.env.NODE_ENV === "development"
|
||||
? "http://localhost:3000"
|
||||
: "https://app.supermemory.ai"
|
||||
}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<LogoFull className="h-8 hidden md:block" />
|
||||
<Logo className="h-8 md:hidden" />
|
||||
</Link>
|
||||
<div className="flex items-center gap-1.5 md:gap-2">
|
||||
<Link
|
||||
className="pointer-events-auto"
|
||||
href={
|
||||
process.env.NODE_ENV === "development"
|
||||
? "http://localhost:3000"
|
||||
: "https://app.supermemory.ai"
|
||||
}
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{getCurrentChat()?.title && pathname.includes("/chat") ? (
|
||||
<div className="flex items-center gap-4">
|
||||
<Logo className="h-6 block text-foreground" />
|
||||
<span className="truncate">{getCurrentChat()?.title}</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<LogoFull className="h-8 hidden md:block" />
|
||||
<Logo className="h-8 md:hidden text-foreground" />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1.5 md:gap-3">
|
||||
<div className="flex items-center gap-1.5 md:gap-2">
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
|
|
@ -76,15 +90,14 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
|||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setGraphModalOpen(true)}
|
||||
className="gap-1.5"
|
||||
>
|
||||
<Network className="h-4 w-4" />
|
||||
<span className="hidden sm:inline">Graph View</span>
|
||||
<WaypointsIcon className="h-5 w-5" />
|
||||
{/*<span className="hidden md:inline">Graph View</span>*/}
|
||||
</Button>
|
||||
<ConnectAIModal>
|
||||
<Button variant="ghost" size="sm" className="gap-1.5">
|
||||
<MCPIcon className="h-4 w-4" />
|
||||
<span className="hidden lg:inline">Connect to AI (MCP)</span>
|
||||
{/*<span className="hidden lg:inline">Connect to AI (MCP)</span>*/}
|
||||
</Button>
|
||||
</ConnectAIModal>
|
||||
<DropdownMenu>
|
||||
|
|
@ -103,15 +116,21 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
|||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={() => router.push("/settings")}>
|
||||
<User className="h-4 w-4 mr-2" />
|
||||
<User className="h-4 w-4" />
|
||||
Profile
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => router.push("/settings/billing")}
|
||||
>
|
||||
<CreditCard className="h-4 w-4 mr-2" />
|
||||
<CreditCard className="h-4 w-4" />
|
||||
Billing
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => router.push("/settings/integrations")}
|
||||
>
|
||||
<Gauge className="h-4 w-4" />
|
||||
Integrations
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
window.open(
|
||||
|
|
@ -121,7 +140,7 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
|||
)
|
||||
}}
|
||||
>
|
||||
<Chrome className="h-4 w-4 mr-2" />
|
||||
<Chrome className="h-4 w-4" />
|
||||
Chrome Extension
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
|
|
@ -188,7 +207,7 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
|
|||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={() => handleSignOut()}>
|
||||
<LogOut className="h-4 w-4 mr-2" />
|
||||
<LogOut className="h-4 w-4" />
|
||||
Logout
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@repo/ui/components/select"
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import {
|
||||
ChevronDown,
|
||||
FolderIcon,
|
||||
|
|
@ -36,7 +36,6 @@ import {
|
|||
} from "lucide-react"
|
||||
import { AnimatePresence, motion } from "motion/react"
|
||||
import { useState } from "react"
|
||||
import { toast } from "sonner"
|
||||
import { useProjectMutations } from "@/hooks/use-project-mutations"
|
||||
import { useProjectName } from "@/hooks/use-project-name"
|
||||
import { useProject } from "@/stores"
|
||||
|
|
@ -52,7 +51,6 @@ interface Project {
|
|||
}
|
||||
|
||||
export function ProjectSelector() {
|
||||
const queryClient = useQueryClient()
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [showCreateDialog, setShowCreateDialog] = useState(false)
|
||||
const { selectedProject } = useProject()
|
||||
|
|
@ -69,13 +67,6 @@ export function ProjectSelector() {
|
|||
action: "move",
|
||||
targetProjectId: DEFAULT_PROJECT_ID,
|
||||
})
|
||||
const [expDialog, setExpDialog] = useState<{
|
||||
open: boolean
|
||||
projectId: string
|
||||
}>({
|
||||
open: false,
|
||||
projectId: "",
|
||||
})
|
||||
|
||||
const { data: projects = [], isLoading } = useQuery({
|
||||
queryKey: ["projects"],
|
||||
|
|
@ -91,30 +82,6 @@ export function ProjectSelector() {
|
|||
staleTime: 30 * 1000,
|
||||
})
|
||||
|
||||
const enableExperimentalMutation = useMutation({
|
||||
mutationFn: async (projectId: string) => {
|
||||
const response = await $fetch(
|
||||
`@post/projects/${projectId}/enable-experimental`,
|
||||
)
|
||||
if (response.error) {
|
||||
throw new Error(
|
||||
response.error?.message || "Failed to enable experimental mode",
|
||||
)
|
||||
}
|
||||
return response.data
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success("Experimental mode enabled for project")
|
||||
queryClient.invalidateQueries({ queryKey: ["projects"] })
|
||||
setExpDialog({ open: false, projectId: "" })
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.error("Failed to enable experimental mode", {
|
||||
description: error instanceof Error ? error.message : "Unknown error",
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const handleProjectSelect = (containerTag: string) => {
|
||||
switchProject(containerTag)
|
||||
setIsOpen(false)
|
||||
|
|
@ -138,7 +105,7 @@ export function ProjectSelector() {
|
|||
</span>
|
||||
<motion.div
|
||||
animate={{ rotate: isOpen ? 180 : 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<ChevronDown className="h-3 w-3" />
|
||||
</motion.div>
|
||||
|
|
@ -165,33 +132,30 @@ export function ProjectSelector() {
|
|||
<div className="p-1.5 max-h-64 overflow-y-auto">
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={`flex items-center justify-between p-2 rounded-md transition-colors cursor-pointer ${
|
||||
className={`flex items-center w-full justify-between p-2 rounded-md transition-colors cursor-pointer ${
|
||||
selectedProject === DEFAULT_PROJECT_ID
|
||||
? "bg-accent"
|
||||
: "hover:bg-accent/50"
|
||||
: "hover:bg-accent/20"
|
||||
}`}
|
||||
onClick={() => handleProjectSelect(DEFAULT_PROJECT_ID)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<FolderIcon className="h-3.5 w-3.5" />
|
||||
<span className="text-xs font-medium">Default</span>
|
||||
<span className="text-xs font-medium">Default Project</span>
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
{/* User Projects */}
|
||||
{projects
|
||||
.filter((p: Project) => p.containerTag !== DEFAULT_PROJECT_ID)
|
||||
.map((project: Project, index: number) => (
|
||||
<motion.div
|
||||
.map((project: Project) => (
|
||||
<div
|
||||
key={project.id}
|
||||
className={`flex items-center justify-between p-2 rounded-md transition-colors group ${
|
||||
selectedProject === project.containerTag
|
||||
? "bg-accent"
|
||||
: "hover:bg-accent/50"
|
||||
}`}
|
||||
initial={{ opacity: 0, x: -5 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: index * 0.03 }}
|
||||
>
|
||||
<button
|
||||
className="flex items-center gap-2 flex-1 cursor-pointer"
|
||||
|
|
@ -208,45 +172,18 @@ export function ProjectSelector() {
|
|||
<div className="flex items-center gap-1">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<motion.button
|
||||
className="p-1 hover:bg-accent rounded transition-all"
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-6 w-6"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.9 }}
|
||||
>
|
||||
<MoreHorizontal className="h-3 w-3" />
|
||||
</motion.button>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{/* Show experimental toggle only if NOT experimental and NOT default project */}
|
||||
{!project.isExperimental &&
|
||||
project.containerTag !== DEFAULT_PROJECT_ID && (
|
||||
<DropdownMenuItem
|
||||
className="text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 cursor-pointer text-xs"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setExpDialog({
|
||||
open: true,
|
||||
projectId: project.id,
|
||||
})
|
||||
setIsOpen(false)
|
||||
}}
|
||||
>
|
||||
<div className="h-3 w-3 mr-2 rounded border border-blue-600 dark:border-blue-400" />
|
||||
Enable Experimental Mode
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{project.isExperimental && (
|
||||
<DropdownMenuItem
|
||||
className="text-blue-600/50 dark:text-blue-300/50 text-xs"
|
||||
disabled
|
||||
>
|
||||
<div className="h-3 w-3 mr-2 rounded bg-blue-600 dark:bg-blue-400" />
|
||||
Experimental Mode Active
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem
|
||||
className="text-red-600 dark:text-red-400 hover:text-red-500 dark:hover:text-red-300 cursor-pointer text-xs"
|
||||
className="cursor-pointer text-xs hover:text-red-500"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setDeleteDialog({
|
||||
|
|
@ -262,13 +199,13 @@ export function ProjectSelector() {
|
|||
setIsOpen(false)
|
||||
}}
|
||||
>
|
||||
<Trash2 className="h-3 w-3 mr-2" />
|
||||
<Trash2 className="h-3 w-3" />
|
||||
Delete Project
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<motion.div
|
||||
|
|
@ -489,82 +426,6 @@ export function ProjectSelector() {
|
|||
</Dialog>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
{/* Experimental Mode Confirmation Dialog */}
|
||||
<AnimatePresence>
|
||||
{expDialog.open && (
|
||||
<Dialog
|
||||
onOpenChange={(open) => setExpDialog({ ...expDialog, open })}
|
||||
open={expDialog.open}
|
||||
>
|
||||
<DialogContent className="sm:max-w-lg">
|
||||
<motion.div
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
className="flex flex-col gap-4"
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Enable Experimental Mode?</DialogTitle>
|
||||
<DialogDescription>
|
||||
Experimental mode enables beta features and advanced memory
|
||||
relationships for this project.
|
||||
<br />
|
||||
<br />
|
||||
<span className="text-yellow-600 dark:text-yellow-400 font-medium">
|
||||
Warning:
|
||||
</span>{" "}
|
||||
This action is{" "}
|
||||
<span className="text-red-600 dark:text-red-400 font-bold">
|
||||
irreversible
|
||||
</span>
|
||||
. Once enabled, you cannot return to regular mode for this
|
||||
project.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Button
|
||||
onClick={() =>
|
||||
setExpDialog({ open: false, projectId: "" })
|
||||
}
|
||||
type="button"
|
||||
variant="outline"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Button
|
||||
className="bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700 text-white"
|
||||
disabled={enableExperimentalMutation.isPending}
|
||||
onClick={() =>
|
||||
enableExperimentalMutation.mutate(expDialog.projectId)
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
{enableExperimentalMutation.isPending ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin mr-2" />
|
||||
Enabling...
|
||||
</>
|
||||
) : (
|
||||
"Enable Experimental Mode"
|
||||
)}
|
||||
</Button>
|
||||
</motion.div>
|
||||
</DialogFooter>
|
||||
</motion.div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1021,7 +1021,6 @@ export function AddMemoryView({
|
|||
>
|
||||
<Label htmlFor="projectName">Project Name</Label>
|
||||
<Input
|
||||
className="bg-white/5 border-white/10"
|
||||
id="projectName"
|
||||
onChange={(e) => setNewProjectName(e.target.value)}
|
||||
placeholder="My Awesome Project"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const Logo = ({
|
|||
<title>supermemory Logo</title>
|
||||
<path
|
||||
d="M205.864 66.263h-76.401V0h-24.684v71.897c0 7.636 3.021 14.97 8.391 20.373l62.383 62.777 17.454-17.564-46.076-46.365h58.948v-24.84l-.015-.015ZM12.872 30.517l46.075 46.365H0v24.84h76.4v66.264h24.685V96.089c0-7.637-3.021-14.97-8.39-20.374l-62.37-62.762-17.453 17.564Z"
|
||||
fill="#EFEFEF"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||
--border: oklch(0.9366 0.0017 247.8401);
|
||||
--input: oklch(0.9702 0 0);
|
||||
--ring: oklch(1 0 0);
|
||||
--ring: oklch(0 0 0);
|
||||
--chart-1: oklch(0.7197 0.1448 266.6983);
|
||||
--chart-2: oklch(0.8101 0.1488 148.2032);
|
||||
--chart-3: oklch(0.7507 0.1353 58.4182);
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||
--border: oklch(0.3715 0 0);
|
||||
--input: oklch(0.262 0.0074 285.8781);
|
||||
--ring: oklch(0 0 0);
|
||||
--ring: oklch(1 0 0);
|
||||
--chart-1: oklch(0.7197 0.1448 266.6983);
|
||||
--chart-2: oklch(0.8101 0.1488 148.2032);
|
||||
--chart-3: oklch(0.7507 0.1353 58.4182);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue