mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Axe landing, fix dashboard routes
This commit is contained in:
parent
3b0eb65457
commit
7268e657c6
24 changed files with 41 additions and 239 deletions
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
|
|
@ -3,7 +3,7 @@
|
|||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { TitleBar } from '@/components/dashboard/TitleBar';
|
||||
import { AnalyticsPage } from '@/features/analytics/AnalyticsPage';
|
||||
import { AnalyticsPage } from '@/components/analytics/AnalyticsPage';
|
||||
|
||||
const AnalyticsPageContainer = () => {
|
||||
const t = useTranslations('Analytics');
|
||||
|
|
@ -5,10 +5,10 @@ import { useState } from 'react';
|
|||
import { Button } from '@/components/ui/button';
|
||||
import { Drawer } from '@/components/ui/drawer';
|
||||
import { TitleBar } from '@/components/dashboard/TitleBar';
|
||||
import { AuditLogDetails } from '@/features/dashboard/AuditLogDetails';
|
||||
import { AuditLogEntry } from '@/features/dashboard/AuditLogEntry';
|
||||
import type { AuditLog } from '@/features/dashboard/mockAuditLogs';
|
||||
import { getFilteredLogs } from '@/features/dashboard/mockAuditLogs';
|
||||
import { AuditLogDetails } from '@/components/dashboard/AuditLogDetails';
|
||||
import { AuditLogEntry } from '@/components/dashboard/AuditLogEntry';
|
||||
import type { AuditLog } from '@/components/dashboard/mockAuditLogs';
|
||||
import { getFilteredLogs } from '@/components/dashboard/mockAuditLogs';
|
||||
|
||||
type TimePeriod = '7' | '30' | '90';
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ import { useTheme } from 'next-themes';
|
|||
import { dark } from '@clerk/themes';
|
||||
import { OrganizationProfile } from '@clerk/nextjs';
|
||||
|
||||
import DefaultParametersPage from '@/features/dashboard/DefaultParametersPage';
|
||||
import ProviderWhitelistPage from '@/features/dashboard/ProviderWhitelistPage';
|
||||
import DefaultParametersPage from '@/components/dashboard/DefaultParametersPage';
|
||||
import ProviderWhitelistPage from '@/components/dashboard/ProviderWhitelistPage';
|
||||
|
||||
export const OrgProfile = () => {
|
||||
const t = useTranslations('OrganizationProfile');
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { TitleBar } from '@/components/dashboard/TitleBar';
|
||||
import { AuditLogCard } from '@/features/dashboard/AuditLogCard';
|
||||
import { UsageAnalyticsCard } from '@/features/dashboard/UsageAnalyticsCard';
|
||||
import { AuditLogCard } from '@/components/dashboard/AuditLogCard';
|
||||
import { UsageAnalyticsCard } from '@/components/dashboard/UsageAnalyticsCard';
|
||||
|
||||
export default function Page() {
|
||||
const t = useTranslations('DashboardIndex');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import '@/styles/globals.css';
|
|||
|
||||
import type { Metadata } from 'next';
|
||||
import { NextIntlClientProvider } from 'next-intl';
|
||||
import { getLocale } from 'next-intl/server';
|
||||
import { getLocale, getTranslations, setRequestLocale } from 'next-intl/server';
|
||||
import { ClerkProvider } from '@clerk/nextjs';
|
||||
|
||||
import { getClerkLocale } from '@/lib/locale';
|
||||
|
|
@ -11,24 +11,31 @@ import { ToastProvider, ToastViewport } from '@/components/ui/toast';
|
|||
import { ToastProvider as ToastContextProvider } from '@/components/ui/toast-context';
|
||||
import { Toaster } from '@/components/ui/toaster';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
icons: [
|
||||
{ rel: 'apple-touch-icon', url: '/apple-touch-icon.png' },
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
sizes: '32x32',
|
||||
url: '/favicon-32x32.png',
|
||||
},
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
sizes: '16x16',
|
||||
url: '/favicon-16x16.png',
|
||||
},
|
||||
{ rel: 'icon', url: '/favicon.ico' },
|
||||
],
|
||||
};
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const locale = await getLocale();
|
||||
const t = await getTranslations({ locale, namespace: 'Index' });
|
||||
|
||||
return {
|
||||
title: t('meta_title'),
|
||||
description: t('meta_description'),
|
||||
icons: [
|
||||
{ rel: 'apple-touch-icon', url: '/apple-touch-icon.png' },
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
sizes: '32x32',
|
||||
url: '/favicon-32x32.png',
|
||||
},
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
sizes: '16x16',
|
||||
url: '/favicon-16x16.png',
|
||||
},
|
||||
{ rel: 'icon', url: '/favicon.ico' },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
|
|
@ -36,6 +43,7 @@ export default async function RootLayout({
|
|||
children: React.ReactNode;
|
||||
}) {
|
||||
const locale = await getLocale();
|
||||
setRequestLocale(locale);
|
||||
|
||||
return (
|
||||
<html lang={locale} suppressHydrationWarning>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,7 @@
|
|||
import { redirect } from 'next/navigation';
|
||||
import { auth as clerkAuth } from '@clerk/nextjs/server';
|
||||
import { getLocale, getTranslations, setRequestLocale } from 'next-intl/server';
|
||||
|
||||
import { Navbar, Footer } from '@/components/layout';
|
||||
import { Hero, Features } from '@/components/landing';
|
||||
|
||||
export async function generateMetadata() {
|
||||
const locale = await getLocale();
|
||||
const t = await getTranslations({ locale, namespace: 'Index' });
|
||||
return { title: t('meta_title'), description: t('meta_description') };
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const { userId } = await clerkAuth();
|
||||
|
||||
if (userId) {
|
||||
redirect('/dashboard');
|
||||
}
|
||||
|
||||
setRequestLocale(await getLocale());
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
<Hero />
|
||||
<Features />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
redirect(userId ? '/dashboard' : '/sign-in');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,148 +0,0 @@
|
|||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { Section } from '@/components/layout';
|
||||
|
||||
export const Features = () => {
|
||||
const t = useTranslations('Features');
|
||||
|
||||
return (
|
||||
<Section className="bg-secondary">
|
||||
<div className="mx-auto mb-12 max-w-screen-md text-center">
|
||||
<div className="bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 bg-clip-text text-sm font-bold text-transparent">
|
||||
{t('section_subtitle')}
|
||||
</div>
|
||||
<div className="mt-1 text-3xl font-bold">{t('section_title')}</div>
|
||||
<div className="mt-2 text-lg text-muted-foreground">
|
||||
{t('section_description')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-x-3 gap-y-8 md:grid-cols-3">
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature1_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature2_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature3_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature4_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature5_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
<FeatureCard
|
||||
icon={
|
||||
<svg
|
||||
className="stroke-primary-foreground stroke-2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" stroke="none" />
|
||||
<path d="M12 3l8 4.5v9L12 21l-8-4.5v-9L12 3M12 12l8-4.5M12 12v9M12 12L4 7.5" />
|
||||
</svg>
|
||||
}
|
||||
title={t('feature6_title')}
|
||||
>
|
||||
{t('feature_description')}
|
||||
</FeatureCard>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
type FeatureCardProps = {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const FeatureCard = ({ icon, title, children }: FeatureCardProps) => (
|
||||
<div className="rounded-xl border border-border bg-card p-5">
|
||||
<div className="size-12 rounded-lg bg-gradient-to-br from-indigo-400 via-purple-400 to-pink-400 p-2 [&_svg]:stroke-white [&_svg]:stroke-2">
|
||||
{icon}
|
||||
</div>
|
||||
<div className="mt-2 text-lg font-bold">{title}</div>
|
||||
<div className="my-3 w-8 border-t border-purple-400" />
|
||||
<div className="mt-2 text-muted-foreground">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { Section } from '@/components/layout/Section';
|
||||
|
||||
export const Hero = () => {
|
||||
const t = useTranslations('Hero');
|
||||
|
||||
return (
|
||||
<Section className="py-36">
|
||||
<div className="mt-3 text-center text-5xl font-bold tracking-tight">
|
||||
{t.rich('title', {
|
||||
important: (chunks) => (
|
||||
<span className="bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 bg-clip-text text-transparent">
|
||||
{chunks}
|
||||
</span>
|
||||
),
|
||||
})}
|
||||
</div>
|
||||
<div className="mx-auto mt-5 max-w-screen-md text-center text-xl text-muted-foreground">
|
||||
{t('description')}
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { Hero } from './Hero';
|
||||
export { Features } from './Features';
|
||||
|
|
@ -2,7 +2,6 @@ import Link from 'next/link';
|
|||
import { useTranslations } from 'next-intl';
|
||||
|
||||
import { Section } from '@/components/layout';
|
||||
import { APP_NAME } from '@/lib/constants';
|
||||
|
||||
export const Footer = () => {
|
||||
const t = useTranslations('Footer');
|
||||
|
|
@ -34,9 +33,7 @@ export const Footer = () => {
|
|||
</li>
|
||||
</ul>
|
||||
<div className="mt-6 flex w-full items-center justify-between gap-y-2 border-t pt-3 text-sm text-muted-foreground max-md:flex-col">
|
||||
<div>
|
||||
© Copyright {new Date().getFullYear()} {APP_NAME}.
|
||||
</div>
|
||||
<div>© Copyright {new Date().getFullYear()} Roo Code.</div>
|
||||
<ul className="flex gap-x-4 font-medium [&_a:hover]:opacity-100 [&_a]:opacity-60">
|
||||
<li>
|
||||
<Link href="/sign-up">{t('terms_of_service')}</Link>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import { APP_NAME } from '@/lib/constants';
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
export const Logo = (props: { isTextHidden?: boolean }) => (
|
||||
export const Logo = () => (
|
||||
<div className="flex items-center text-xl font-semibold">
|
||||
<Image
|
||||
src="/Roo-Code-Logo-Horiz-blk.svg"
|
||||
src="/logo.svg"
|
||||
alt="Roo Code Logo"
|
||||
width={120}
|
||||
height={26}
|
||||
|
|
@ -13,13 +11,12 @@ export const Logo = (props: { isTextHidden?: boolean }) => (
|
|||
style={{ height: 'auto' }}
|
||||
/>
|
||||
<Image
|
||||
src="/Roo-Code-Logo-Horiz-white.svg"
|
||||
src="/logo-dark.svg"
|
||||
alt="Roo Code Logo"
|
||||
width={120}
|
||||
height={26}
|
||||
className="mr-2 hidden dark:block"
|
||||
style={{ height: 'auto' }}
|
||||
/>
|
||||
{!props.isTextHidden && APP_NAME}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
export const APP_NAME = 'Roo Code Cloud';
|
||||
Loading…
Add table
Reference in a new issue