diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx index 8e9392cc5..ca4f5a195 100644 --- a/frontend/src/app/router.tsx +++ b/frontend/src/app/router.tsx @@ -225,6 +225,21 @@ const createAppRouter = () => } } }, + { + path: 'ii-claw', + async lazy() { + const { Component } = await import( + '@/app/routes/ii-claw' + ) + return { + Component: () => ( + + + + ) + } + } + }, { path: 'share/:sessionId', async lazy() { diff --git a/frontend/src/app/routes/ii-claw.tsx b/frontend/src/app/routes/ii-claw.tsx new file mode 100644 index 000000000..98d2b8a1d --- /dev/null +++ b/frontend/src/app/routes/ii-claw.tsx @@ -0,0 +1,226 @@ +'use client' + +import { useState } from 'react' +import { useNavigate } from 'react-router' +import { useTranslation } from 'react-i18next' +import clsx from 'clsx' + +import { Logo } from '@/components/logo' +import { Icon } from '@/components/ui/icon' +import { + SidebarProvider, + SidebarTrigger +} from '@/components/ui/sidebar' +import Sidebar from '@/components/sidebar' +import { useIsSageTheme } from '@/hooks/use-is-sage-theme' +import { useIsMobile } from '@/hooks/use-mobile' +import { ChannelsPanel } from '@/components/ii-claw/channels' +import { CronJobsPanel } from '@/components/ii-claw/cron-jobs' +import { AgentsPanel } from '@/components/ii-claw/agents' + +type ClawTab = 'agents' | 'channels' | 'cronjobs' + +const CLAW_SIDEBAR_ITEMS: { + key: ClawTab + label: string + iconName: string + i18nKey: string +}[] = [ + { key: 'agents', label: 'Agents', iconName: 'agent', i18nKey: 'iiClaw.agents.title' }, + { key: 'channels', label: 'Channels', iconName: 'connector', i18nKey: 'iiClaw.channels.title' }, + { key: 'cronjobs', label: 'Cron Jobs', iconName: 'clock', i18nKey: 'iiClaw.cronJobs.title' }, +] + +// --------------------------------------------------------------------------- +// Desktop Sidebar +// --------------------------------------------------------------------------- + +const ClawDesktopSidebar = ({ + activeTab, + setActiveTab, + handleBack, + isSage +}: { + activeTab: ClawTab + setActiveTab: (tab: ClawTab) => void + handleBack: () => void + isSage: boolean +}) => { + const { t } = useTranslation() + + return ( +
+
+
+ + +
+
+ + + +
+

+ {t('iiClaw.version')} +

+
+
+ ) +} + +// --------------------------------------------------------------------------- +// Mobile Layout +// --------------------------------------------------------------------------- + +const IIClawMobile = ({ + activeTab, + setActiveTab, + renderContent, + handleBack +}: { + activeTab: ClawTab + setActiveTab: (tab: ClawTab) => void + renderContent: () => React.ReactNode + handleBack: () => void +}) => { + const { t } = useTranslation() + + return ( + + +
+
+
+ + + {t('iiClaw.title')} + +
+ +
+ +
+ {CLAW_SIDEBAR_ITEMS.map((item) => ( + + ))} +
+ +
{renderContent()}
+
+
+ ) +} + +// --------------------------------------------------------------------------- +// Main Component +// --------------------------------------------------------------------------- + +const IIClaw = () => { + const navigate = useNavigate() + const isSage = useIsSageTheme() + const isMobile = useIsMobile() + const [activeTab, setActiveTab] = useState('agents') + + const handleBack = () => { + navigate(-1) + } + + const renderContent = () => { + switch (activeTab) { + case 'agents': + return + case 'channels': + return + case 'cronjobs': + return + default: + return null + } + } + + if (isMobile) { + return ( + + ) + } + + return ( +
+ +
+ {renderContent()} +
+
+ ) +} + +export { IIClaw as Component } diff --git a/frontend/src/components/home-mobile.tsx b/frontend/src/components/home-mobile.tsx index 3e07cd24b..e2b287dd6 100644 --- a/frontend/src/components/home-mobile.tsx +++ b/frontend/src/components/home-mobile.tsx @@ -20,6 +20,7 @@ import { } from '@/state' import { AGENT_TYPE, QUESTION_MODE } from '@/typings/agent' import { SidebarTrigger } from './ui/sidebar' +import { Link } from 'react-router' import { useTranslation } from 'react-i18next' import QuestionInput from './question-input' import type { @@ -347,6 +348,12 @@ const HomeMobile = ({
+ + +