Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/web-roo-code/public/adam-larson.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/web-roo-code/public/ai-code-king.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
150 changes: 150 additions & 0 deletions apps/web-roo-code/src/app/icon-test/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"use client"

import { FaRobot, FaCode, FaBrain, FaGlobe, FaTerminal, FaPuzzlePiece } from "react-icons/fa"
import {
FaRobot as Fa6Robot,
FaCode as Fa6Code,
FaBrain as Fa6Brain,
FaGlobe as Fa6Globe,
FaPuzzlePiece as Fa6PuzzlePiece,
} from "react-icons/fa6"
import { Bot, Code2, Brain, Globe, Terminal, Puzzle } from "lucide-react"

export default function IconTestPage() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test page intended for production? It appears to be a development utility for comparing icon libraries. Consider either:

  1. Moving it to a development-only route
  2. Adding authentication/environment checks
  3. Removing it before merging

If it's meant for internal use, you might want to protect it behind authentication.

const iconSets = [
{
title: "Font Awesome 5 (react-icons/fa) - Currently Used",
description: "Icons from react-icons/fa - what we're using now",
icons: [
{ icon: <FaRobot className="h-6 w-6" />, label: "FaRobot" },
{ icon: <FaPuzzlePiece className="h-6 w-6" />, label: "FaPuzzlePiece" },
{ icon: <FaBrain className="h-6 w-6" />, label: "FaBrain" },
{ icon: <FaGlobe className="h-6 w-6" />, label: "FaGlobe" },
{ icon: <FaCode className="h-6 w-6" />, label: "FaCode" },
{ icon: <FaTerminal className="h-6 w-6" />, label: "FaTerminal" },
],
wrapperClass:
"mb-5 inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-blue-500/5 to-cyan-500/5 p-2.5",
innerClass: "rounded-lg bg-gradient-to-r from-blue-500/80 to-cyan-500/80 p-2.5",
iconClass: "text-foreground/90",
},
{
title: "Font Awesome 6 (react-icons/fa6)",
description: "Icons from react-icons/fa6 - newer version",
icons: [
{ icon: <Fa6Robot className="h-6 w-6" />, label: "Fa6Robot" },
{ icon: <Fa6PuzzlePiece className="h-6 w-6" />, label: "Fa6PuzzlePiece" },
{ icon: <Fa6Brain className="h-6 w-6" />, label: "Fa6Brain" },
{ icon: <Fa6Globe className="h-6 w-6" />, label: "Fa6Globe" },
{ icon: <Fa6Code className="h-6 w-6" />, label: "Fa6Code" },
],
wrapperClass:
"mb-5 inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-blue-500/5 to-cyan-500/5 p-2.5",
innerClass: "rounded-lg bg-gradient-to-r from-blue-500/80 to-cyan-500/80 p-2.5",
iconClass: "text-foreground/90",
},
{
title: "Lucide React Icons",
description: "Alternative icons from lucide-react",
icons: [
{ icon: <Bot className="h-6 w-6" />, label: "Bot" },
{ icon: <Puzzle className="h-6 w-6" />, label: "Puzzle" },
{ icon: <Brain className="h-6 w-6" />, label: "Brain" },
{ icon: <Globe className="h-6 w-6" />, label: "Globe" },
{ icon: <Code2 className="h-6 w-6" />, label: "Code2" },
{ icon: <Terminal className="h-6 w-6" />, label: "Terminal" },
],
wrapperClass:
"mb-5 inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-blue-500/5 to-cyan-500/5 p-2.5",
innerClass: "rounded-lg bg-gradient-to-r from-blue-500/80 to-cyan-500/80 p-2.5",
iconClass: "text-foreground/90",
},
{
title: "Raw Icons Comparison (No Styling)",
description: "All icon sets without wrapper styling",
icons: [
{ icon: <FaRobot className="h-8 w-8" />, label: "FA5 Robot" },
{ icon: <Fa6Robot className="h-8 w-8" />, label: "FA6 Robot" },
{ icon: <Bot className="h-8 w-8" />, label: "Lucide Bot" },
{ icon: <FaPuzzlePiece className="h-8 w-8" />, label: "FA5 Puzzle" },
{ icon: <Fa6PuzzlePiece className="h-8 w-8" />, label: "FA6 Puzzle" },
{ icon: <Puzzle className="h-8 w-8" />, label: "Lucide Puzzle" },
],
wrapperClass: "",
innerClass: "",
iconClass: "",
},
]

return (
<div className="min-h-screen bg-background p-8">
<div className="mx-auto max-w-7xl">
<h1 className="mb-8 text-3xl font-bold">Icon Library Comparison</h1>

<div className="mb-8 rounded-lg bg-muted p-4">
<p className="text-sm mb-2">
<strong>Current Setup:</strong> React Icons v5.5.0 (from package.json)
</p>
<p className="text-sm mb-2">
This page compares different icon libraries to identify which ones match the production site.
</p>
<p className="text-sm">
The production site at https://roocode.com might be using a different icon set or version.
</p>
</div>

{iconSets.map((set, setIndex) => (
<div key={setIndex} className="mb-12 border-b border-border pb-8">
<h2 className="mb-2 text-xl font-semibold">{set.title}</h2>
<p className="mb-6 text-sm text-muted-foreground">{set.description}</p>

<div className="grid grid-cols-3 gap-8 md:grid-cols-6">
{set.icons.map((item, index) => (
<div key={index} className="text-center">
{set.wrapperClass ? (
<div className={set.wrapperClass}>
<div className={set.innerClass}>
<div className={set.iconClass}>{item.icon}</div>
</div>
</div>
) : (
<div className="mb-5 inline-flex items-center justify-center p-4">
{item.icon}
</div>
)}
<p className="text-xs font-medium">{item.label}</p>
</div>
))}
</div>
</div>
))}

<div className="mt-12 space-y-4 rounded-lg bg-muted p-6">
<h3 className="text-lg font-semibold">Visual Differences to Look For:</h3>
<ul className="space-y-2 text-sm list-disc list-inside">
<li>Font Awesome 5 vs 6: FA6 icons often have slightly different designs and weights</li>
<li>Lucide icons: Generally have a more consistent stroke width and modern design</li>
<li>The robot icon in FA5 vs FA6 has notable differences in design</li>
<li>The puzzle piece icon also varies between versions</li>
</ul>
</div>

<div className="mt-8 flex gap-4">
<a href="/" className="rounded-lg bg-primary px-4 py-2 text-primary-foreground">
Go to Homepage
</a>
<a href="/roomote-control" className="rounded-lg bg-primary px-4 py-2 text-primary-foreground">
Go to Roomote Control
</a>
<a
href="https://roocode.com"
target="_blank"
rel="noopener noreferrer"
className="rounded-lg bg-secondary px-4 py-2 text-secondary-foreground">
View Production Site
</a>
</div>
</div>
</div>
)
}
54 changes: 54 additions & 0 deletions apps/web-roo-code/src/app/roomote-control/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Metadata } from "next"
import { RoomoteHero } from "@/components/roomote-control/hero"
import { NarrativeBand } from "@/components/roomote-control/narrative-band"
import { HowItWorks } from "@/components/roomote-control/how-it-works"
import { FeatureGrid } from "@/components/roomote-control/feature-grid"
import { RoomoteTestimonials } from "@/components/roomote-control/testimonials"
import { RoomoteFAQ } from "@/components/roomote-control/faq"
import { FinalCTA } from "@/components/roomote-control/final-cta"

export const metadata: Metadata = {
title: "Roo Code Cloud | Roomote Control – Manage coding tasks from mobile & web browser in addition to the IDE",
description:
"Roomote Control keeps coding moving, wherever you are. Start tasks in your editor, manage them from your phone or browser, and watch your workspace mirror into the cloud.",
alternates: {
canonical: "https://roocode.com/roomote-control",
},
openGraph: {
title: "Roo Code Cloud | Roomote Control",
description:
"Manage coding tasks from mobile & web browser in addition to the IDE. Your first truly hybrid coding teammate.",
url: "https://roocode.com/roomote-control",
siteName: "Roo Code",
images: [
{
url: "https://roocode.com/og-roomote-control.png",
width: 1200,
height: 630,
alt: "Roomote Control - Hybrid coding across IDE, cloud, and mobile",
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Roo Code Cloud | Roomote Control",
description: "Manage coding tasks from mobile & web browser in addition to the IDE",
images: ["https://roocode.com/og-roomote-control.png"],
},
}

export default function RoomoteControlPage() {
return (
<>
<RoomoteHero />
<NarrativeBand />
<HowItWorks />
<FeatureGrid />
<RoomoteTestimonials />
<RoomoteFAQ />
<FinalCTA />
</>
)
}
144 changes: 144 additions & 0 deletions apps/web-roo-code/src/components/roomote-control/faq.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"use client"

import { useState } from "react"
import { motion } from "framer-motion"
import { ChevronDown } from "lucide-react"
import { cn } from "@/lib/utils"

interface FAQItem {
question: string
answer: string
}

const faqs: FAQItem[] = [
{
question: "What is Roo Code Cloud?",
answer: "Roo Code Cloud is a web-based platform that extends your Roo Code extension with cloud-powered features. By connecting your local VS Code extension to the cloud, you unlock task sharing, usage analytics, and remote control options that enhance your AI-assisted development workflow. [Learn more](https://docs.roocode.com/roo-code-cloud/what-is-roo-code-cloud).",
},
{
question: "What is Roomote Control?",
answer: "Roomote Control creates a bidirectional connection between your local extension and Roo Code Cloud, enabling real-time monitoring and control of Roo Code tasks running in your extension directly from the Roo Code Cloud mobile or web interface. [Learn more](https://docs.roocode.com/roo-code-cloud/roomote-control).",
},
{
question: "How do I enable Roomote Control?",
answer: "Open the Roo Code extension, go to the Account tab, and toggle on Roomote Control. Sign in with GitHub, Google, or email to connect your extension to Roo Code Cloud. Once connected, your workspace appears under Connected Workspaces and your tasks automatically sync across devices and sessions. Learn more about [Login/Signup](https://docs.roocode.com/roo-code-cloud/login).",
},
{
question: "Can I disable it?",
answer: "Yes. Toggle off anytime or log out of Roo Cloud.",
},
{
question: "Is my code safe?",
answer: "Roo only shares the context needed for tasks, not your full repo. Run Roo in your own infrastructure with confidence. See our [Roo Code Cloud docs](https://docs.roocode.com/roo-code-cloud/what-is-roo-code-cloud) and [Roo Code Trust Center](https://trust.roocode.com/) for additional security details.",
},
{
question: "What is free vs. paid?",
answer: "Free users can monitor tasks in real time and view previously logged work in Roo Code Cloud. Pro ($20/mo after free 14-day trial) unlocks full Roomote Control — start, stop, create, edit, and manage tasks remotely. Cancel anytime, no commitment. Learn more about [Free vs. Paid Features](https://docs.roocode.com/roo-code-cloud/billing-subscriptions#pro-plan-20month).",
},
{
question: "How does billing work?",
answer: "Pro is billed at $20 per user, per month. Plans are month-to-month, and you can cancel anytime. Billing is handled through Stripe, and no credit card is required to start with the free plan. Learn more about [Billing & Subscriptions](https://docs.roocode.com/roo-code-cloud/billing-subscriptions).",
},
{
question: 'What does "priority support" include?',
answer: "Pro subscribers get faster responses from the Roo Code team on Discord and email, as well as early access to new features and roadmap previews. Learn more about [Plan Tiers](https://docs.roocode.com/roo-code-cloud/billing-subscriptions).",
},
{
question: "Are there any limits in the free plan?",
answer: "Free users can monitor and view logged tasks, but cannot start new tasks from the web or exercise full edit controls. Learn more about [Plan Tiers](https://docs.roocode.com/roo-code-cloud/billing-subscriptions).",
},
{
question: "Which builds are supported?",
answer: "Latest Roo Code extension and a connected Git provider.",
},
{
question: "What about notifications?",
answer: 'Completion notifications are rolling out shortly. Features marked "coming soon" are actively in development and will be available to all users as they launch.',
},
{
question: "Can I share tasks with teammates?",
answer: "Yes. You can share individual tasks with colleagues or the community through secure, expiring links. Control what you share and when, with links that automatically expire after 30 days for enhanced security. Learn more about [Task Sharing](https://docs.roocode.com/roo-code-cloud/task-sharing).",
},
]

export function RoomoteFAQ() {
const [openIndex, setOpenIndex] = useState<number | null>(null)

const toggleFAQ = (index: number) => {
setOpenIndex(openIndex === index ? null : index)
}

return (
<section className="border-t border-border py-20 md:py-32">
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, ease: [0.21, 0.45, 0.27, 0.9] }}
className="mx-auto mb-16 max-w-3xl text-center">
<h2 className="mb-6 text-3xl font-bold tracking-tight sm:text-4xl">FAQ</h2>
</motion.div>

<div className="mx-auto max-w-3xl">
<div className="space-y-4">
{faqs.map((faq, index) => (
<motion.div
key={index}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{
duration: 0.5,
delay: index * 0.1,
ease: [0.21, 0.45, 0.27, 0.9],
}}>
<div className="group relative rounded-lg border border-border/50 bg-background/30 backdrop-blur-xl transition-all duration-300 hover:border-border">
<button
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we improve accessibility here? The accordion needs better ARIA attributes. Consider adding aria-controls and id attributes to properly link the button and content elements for screen readers.

onClick={() => toggleFAQ(index)}
className="flex w-full items-center justify-between p-6 text-left"
aria-expanded={openIndex === index}>
<h3 className="pr-4 text-lg font-medium text-foreground/90">{faq.question}</h3>
<ChevronDown
className={cn(
"h-5 w-5 flex-shrink-0 text-muted-foreground transition-transform duration-200",
openIndex === index ? "rotate-180" : "",
)}
/>
</button>
<div
className={cn(
"overflow-hidden transition-all duration-300 ease-in-out",
openIndex === index ? "max-h-96 pb-6" : "max-h-0",
)}>
<div className="px-6 text-muted-foreground">
<p>
{faq.answer.split(/(\[.*?\]\(.*?\))/).map((part, i) => {
// Handle markdown-style links
const linkMatch = part.match(/\[(.*?)\]\((.*?)\)/)
if (linkMatch) {
return (
<a
key={i}
href={linkMatch[2]}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 underline-offset-4 hover:underline">
{linkMatch[1]}
</a>
)
}
return part
})}
</p>
</div>
</div>
</div>
</motion.div>
))}
</div>
</div>
</div>
</section>
)
}
Loading
Loading