mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat(web): add install modal with multi-editor options
This commit is contained in:
parent
0cd257af89
commit
ac656dabd6
3 changed files with 166 additions and 17 deletions
|
|
@ -13,6 +13,7 @@ import { EXTERNAL_LINKS } from "@/lib/constants"
|
|||
import { useLogoSrc } from "@/lib/hooks/use-logo-src"
|
||||
import { ScrollButton } from "@/components/ui"
|
||||
import ThemeToggle from "@/components/chromes/theme-toggle"
|
||||
import { InstallModal } from "@/components/homepage/install-modal"
|
||||
import { Brain, Cloud, Puzzle, Slack, X } from "lucide-react"
|
||||
import {
|
||||
NavigationMenu,
|
||||
|
|
@ -40,6 +41,7 @@ interface NavBarProps {
|
|||
|
||||
export function NavBar({ stars, downloads }: NavBarProps) {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||
const [isInstallModalOpen, setIsInstallModalOpen] = useState(false)
|
||||
const logoSrc = useLogoSrc()
|
||||
|
||||
return (
|
||||
|
|
@ -202,16 +204,15 @@ export function NavBar({ stars, downloads }: NavBarProps) {
|
|||
className="hidden items-center gap-1.5 rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground transition-all duration-200 hover:shadow-lg hover:scale-105 md:flex">
|
||||
Sign Up
|
||||
</a>
|
||||
<Link
|
||||
href={EXTERNAL_LINKS.MARKETPLACE}
|
||||
target="_blank"
|
||||
<button
|
||||
onClick={() => setIsInstallModalOpen(true)}
|
||||
className="hidden items-center gap-1.5 rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground transition-all duration-200 hover:shadow-lg hover:scale-105 md:flex whitespace-nowrap">
|
||||
<VscVscode className="-mr-[2px] mt-[1px] h-4 w-4" />
|
||||
<span>
|
||||
Install <span className="font-black max-lg:text-xs">·</span>
|
||||
</span>
|
||||
{downloads !== null && <span>{downloads}</span>}
|
||||
</Link>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
|
|
@ -332,14 +333,15 @@ export function NavBar({ stars, downloads }: NavBarProps) {
|
|||
<div className="flex items-center rounded-md p-3 transition-colors hover:bg-accent">
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
<Link
|
||||
href={EXTERNAL_LINKS.MARKETPLACE}
|
||||
target="_blank"
|
||||
className="inline-flex items-center gap-2 rounded-md p-3 text-sm transition-colors hover:bg-accent hover:text-foreground"
|
||||
onClick={() => setIsMenuOpen(false)}>
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsMenuOpen(false)
|
||||
setIsInstallModalOpen(true)
|
||||
}}
|
||||
className="inline-flex items-center gap-2 rounded-md p-3 text-sm transition-colors hover:bg-accent hover:text-foreground">
|
||||
<VscVscode className="h-6 w-6" />
|
||||
{downloads !== null && <span>{downloads}</span>}
|
||||
</Link>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex gap-2 px-4 pb-4">
|
||||
<a
|
||||
|
|
@ -362,6 +364,9 @@ export function NavBar({ stars, downloads }: NavBarProps) {
|
|||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Install Modal */}
|
||||
<InstallModal open={isInstallModalOpen} onOpenChange={setIsInstallModalOpen} />
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
139
apps/web-roo-code/src/components/homepage/install-modal.tsx
Normal file
139
apps/web-roo-code/src/components/homepage/install-modal.tsx
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
"use client"
|
||||
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/modal"
|
||||
import { motion } from "framer-motion"
|
||||
|
||||
interface Editor {
|
||||
name: string
|
||||
icon: React.ReactNode
|
||||
href: string
|
||||
}
|
||||
|
||||
// VS Code icon
|
||||
const VSCodeIcon = () => (
|
||||
<svg viewBox="0 0 100 100" className="w-full h-full" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M74.5 13.5L39.5 45L21.5 30.5L13.5 34V66L21.5 69.5L39.5 55L74.5 86.5L86.5 81.5V18.5L74.5 13.5Z"
|
||||
fill="#007ACC"
|
||||
/>
|
||||
<path d="M74.5 13.5L39.5 45L21.5 30.5L13.5 34V66L21.5 69.5L39.5 55L74.5 86.5" fill="#1F9CF0" />
|
||||
<path d="M21.5 30.5L13.5 34V66L21.5 69.5V30.5Z" fill="#0065A9" />
|
||||
<path d="M74.5 13.5L86.5 18.5V81.5L74.5 86.5V13.5Z" fill="#0065A9" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
// VS Code Insiders icon
|
||||
const VSCodeInsidersIcon = () => (
|
||||
<svg viewBox="0 0 100 100" className="w-full h-full" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M74.5 13.5L39.5 45L21.5 30.5L13.5 34V66L21.5 69.5L39.5 55L74.5 86.5L86.5 81.5V18.5L74.5 13.5Z"
|
||||
fill="#24BFA5"
|
||||
/>
|
||||
<path d="M74.5 13.5L39.5 45L21.5 30.5L13.5 34V66L21.5 69.5L39.5 55L74.5 86.5" fill="#3DC9A9" />
|
||||
<path d="M21.5 30.5L13.5 34V66L21.5 69.5V30.5Z" fill="#1A9E82" />
|
||||
<path d="M74.5 13.5L86.5 18.5V81.5L74.5 86.5V13.5Z" fill="#1A9E82" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
// Cursor icon
|
||||
const CursorIcon = () => (
|
||||
<svg viewBox="0 0 100 100" className="w-full h-full" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" rx="12" fill="#1E1E1E" />
|
||||
<path d="M30 25L70 50L30 75V25Z" fill="none" stroke="#FFFFFF" strokeWidth="6" strokeLinejoin="round" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
// Windsurf icon
|
||||
const WindsurfIcon = () => (
|
||||
<svg viewBox="0 0 100 100" className="w-full h-full" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" rx="12" fill="#0F0F0F" />
|
||||
<path
|
||||
d="M25 65L40 35L55 55L75 25"
|
||||
fill="none"
|
||||
stroke="#06B6D4"
|
||||
strokeWidth="6"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M25 75L50 50L75 75"
|
||||
fill="none"
|
||||
stroke="#8B5CF6"
|
||||
strokeWidth="6"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
const editors: Editor[] = [
|
||||
{
|
||||
name: "VS Code",
|
||||
icon: <VSCodeIcon />,
|
||||
href: "vscode:extension/RooVeterinaryInc.roo-cline",
|
||||
},
|
||||
{
|
||||
name: "VS Code Insiders",
|
||||
icon: <VSCodeInsidersIcon />,
|
||||
href: "vscode-insiders:extension/RooVeterinaryInc.roo-cline",
|
||||
},
|
||||
{
|
||||
name: "Cursor",
|
||||
icon: <CursorIcon />,
|
||||
href: "cursor:extension/RooVeterinaryInc.roo-cline",
|
||||
},
|
||||
{
|
||||
name: "Windsurf",
|
||||
icon: <WindsurfIcon />,
|
||||
href: "windsurf:extension/RooVeterinaryInc.roo-cline",
|
||||
},
|
||||
]
|
||||
|
||||
interface InstallModalProps {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
export function InstallModal({ open, onOpenChange }: InstallModalProps) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[500px] p-6">
|
||||
<DialogHeader className="text-center pb-4">
|
||||
<DialogTitle className="text-2xl font-bold text-center">Install Roo Code</DialogTitle>
|
||||
<DialogDescription className="text-center text-muted-foreground">Select your IDE</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-2 max-h-[60vh] overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
|
||||
{editors.map((editor, index) => (
|
||||
<motion.div
|
||||
key={editor.name}
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: index * 0.05, duration: 0.3 }}
|
||||
className="group relative">
|
||||
<div className="relative flex items-center gap-3 p-2.5 bg-muted/30 border border-border/50 rounded-lg hover:bg-muted/50 hover:border-border transition-colors duration-150">
|
||||
<div className="relative flex-shrink-0">
|
||||
<div className="w-12 h-12 bg-background shadow-sm border border-border/50 rounded-lg p-2 overflow-hidden">
|
||||
{editor.icon}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-grow min-w-0">
|
||||
<h3 className="text-base font-semibold text-foreground">{editor.name}</h3>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<a
|
||||
href={editor.href}
|
||||
target={editor.href.startsWith("http") ? "_blank" : undefined}
|
||||
rel={editor.href.startsWith("http") ? "noopener noreferrer" : undefined}
|
||||
className="px-4 py-2 bg-primary hover:bg-primary/90 active:bg-primary/80 text-primary-foreground text-xs font-semibold rounded-md transition-colors duration-150 shadow-sm">
|
||||
Install
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,14 +1,17 @@
|
|||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { VscVscode } from "react-icons/vsc"
|
||||
import Link from "next/link"
|
||||
import { motion } from "framer-motion"
|
||||
import { InstallModal } from "./install-modal"
|
||||
|
||||
interface InstallSectionProps {
|
||||
downloads: string | null
|
||||
}
|
||||
|
||||
export function InstallSection({ downloads }: InstallSectionProps) {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
||||
|
||||
const backgroundVariants = {
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
|
|
@ -57,16 +60,15 @@ export function InstallSection({ downloads }: InstallSectionProps) {
|
|||
</p>
|
||||
|
||||
<div className="mt-12 flex flex-col items-center justify-center gap-6">
|
||||
{/* Enhanced VSCode Marketplace button */}
|
||||
<Link
|
||||
href="https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline"
|
||||
target="_blank"
|
||||
{/* Install button that opens modal */}
|
||||
<button
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
className="group relative inline-flex w-full items-center justify-center gap-3 rounded-xl bg-gradient-to-r from-blue-600 to-cyan-600 px-6 py-4 text-lg font-medium text-white shadow-lg transition-all duration-300 hover:from-blue-700 hover:to-cyan-700 hover:shadow-xl hover:shadow-blue-500/25 dark:from-blue-500 dark:to-cyan-500 dark:hover:from-blue-600 dark:hover:to-cyan-600 sm:w-auto sm:px-8 sm:text-xl">
|
||||
<div className="absolute -inset-px rounded-xl bg-gradient-to-r from-blue-400 via-cyan-400 to-blue-400 opacity-0 blur transition-opacity duration-500 group-hover:opacity-70" />
|
||||
<div className="relative flex flex-col md:flex-row items-center md:gap-3">
|
||||
<VscVscode className="h-6 w-6 shrink-0" />
|
||||
<span className="flex flex-col md:flex-row items-center md:gap-2">
|
||||
<span>From VS Code Marketplace</span>
|
||||
<span>Install Roo Code</span>
|
||||
{downloads !== null && (
|
||||
<>
|
||||
<span className="font-black opacity-60 hidden md:inline">
|
||||
|
|
@ -77,7 +79,7 @@ export function InstallSection({ downloads }: InstallSectionProps) {
|
|||
)}
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
</button>
|
||||
|
||||
{/* Enhanced CLI install section */}
|
||||
<div className="group relative w-full max-w-xl">
|
||||
|
|
@ -100,6 +102,9 @@ export function InstallSection({ downloads }: InstallSectionProps) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Install Modal */}
|
||||
<InstallModal open={isModalOpen} onOpenChange={setIsModalOpen} />
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue