diff --git a/index.html b/index.html index 5018715..9cc75af 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,37 @@ Claudia - Claude Code Session Browser + + diff --git a/public/fonts/MapleMono-Bold.ttf b/public/fonts/MapleMono-Bold.ttf new file mode 100644 index 0000000..ec169c3 Binary files /dev/null and b/public/fonts/MapleMono-Bold.ttf differ diff --git a/public/fonts/MapleMono-Light.ttf b/public/fonts/MapleMono-Light.ttf new file mode 100644 index 0000000..92342bb Binary files /dev/null and b/public/fonts/MapleMono-Light.ttf differ diff --git a/public/fonts/MapleMono-Regular.ttf b/public/fonts/MapleMono-Regular.ttf new file mode 100644 index 0000000..fac41a9 Binary files /dev/null and b/public/fonts/MapleMono-Regular.ttf differ diff --git a/public/fonts/MapleMono-SemiBold.ttf b/public/fonts/MapleMono-SemiBold.ttf new file mode 100644 index 0000000..208fc46 Binary files /dev/null and b/public/fonts/MapleMono-SemiBold.ttf differ diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000..4dfba60 Binary files /dev/null and b/public/icon.png differ diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0530fc2..438c14b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -13,8 +13,8 @@ "windows": [ { "title": "Claudia", - "width": 800, - "height": 600 + "width": 1600, + "height": 1200 } ], "security": { diff --git a/src/App.tsx b/src/App.tsx index e9ec114..24e2c27 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,11 @@ import { useState, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; -import { Plus, Loader2, Bot, FolderCode } from "lucide-react"; +import { Plus, Loader2, ArrowLeft } from "lucide-react"; import { api, type Project, type Session, type ClaudeMdFile } from "@/lib/api"; import { OutputCacheProvider } from "@/lib/outputCache"; import { TabProvider } from "@/contexts/TabContext"; import { ThemeProvider } from "@/contexts/ThemeContext"; import { Button } from "@/components/ui/button"; -import { Card } from "@/components/ui/card"; import { ProjectList } from "@/components/ProjectList"; import { SessionList } from "@/components/SessionList"; import { RunningClaudeSessions } from "@/components/RunningClaudeSessions"; @@ -28,6 +27,7 @@ import { useTabState } from "@/hooks/useTabState"; import { AnalyticsConsentBanner } from "@/components/AnalyticsConsent"; import { useAppLifecycle, useTrackEvent } from "@/hooks"; import { useTranslation } from "@/hooks/useTranslation"; +import { WelcomePage } from "@/components/WelcomePage"; type View = | "welcome" @@ -50,7 +50,7 @@ type View = */ function AppContent() { const { t } = useTranslation(); - const [view, setView] = useState("tabs"); + const [view, setView] = useState("welcome"); const { createClaudeMdTab, createSettingsTab, createUsageTab, createMCPTab } = useTabState(); const [projects, setProjects] = useState([]); const [selectedProject, setSelectedProject] = useState(null); @@ -149,6 +149,18 @@ function AppContent() { }; }, []); + // Listen for switch to welcome view event + useEffect(() => { + const handleSwitchToWelcome = () => { + setView("welcome"); + }; + + window.addEventListener('switch-to-welcome', handleSwitchToWelcome); + return () => { + window.removeEventListener('switch-to-welcome', handleSwitchToWelcome); + }; + }, []); + /** * Loads all projects from the ~/.claude/projects directory */ @@ -219,9 +231,9 @@ function AppContent() { /** * Handles view changes with navigation protection */ - const handleViewChange = (newView: View) => { + const handleViewChange = (newView: string) => { // No need for navigation protection with tabs since sessions stay open - setView(newView); + setView(newView as View); }; /** @@ -237,60 +249,10 @@ function AppContent() { switch (view) { case "welcome": return ( -
-
- {/* Welcome Header */} - -

- - {t('welcomeToClaudia')} -

-
- - {/* Navigation Cards */} -
- {/* CC Agents Card */} - - handleViewChange("cc-agents")} - > -
- -

{t('ccAgents')}

-
-
-
- - {/* CC Projects Card */} - - handleViewChange("projects")} - > -
- -

{t('ccProjects')}

-
-
-
- -
-
-
+ ); case "cc-agents": @@ -325,19 +287,20 @@ function AppContent() { transition={{ duration: 0.5 }} className="mb-6" > - -
-

{t('ccProjects')}

-

- {t('browseClaudeCodeSessions')} -

+
+ +
+

{t('ccProjects')}

+

+ {t('browseClaudeCodeSessions')} +

+
@@ -375,6 +338,19 @@ function AppContent() { projectPath={selectedProject.path} onBack={handleBack} onEditClaudeFile={handleEditClaudeFile} + onSessionClick={(session) => { + // Navigate to session detail view in tabs mode + setView("tabs"); + // Create a new tab for this session + setTimeout(() => { + window.dispatchEvent(new CustomEvent('open-session-tab', { + detail: { + session, + projectPath: selectedProject.path + } + })); + }, 100); + }} /> ) : ( @@ -480,19 +456,19 @@ function AppContent() {
{/* Topbar */} createClaudeMdTab()} - onSettingsClick={() => createSettingsTab()} - onUsageClick={() => createUsageTab()} - onMCPClick={() => createMCPTab()} + onClaudeClick={() => view === 'tabs' ? createClaudeMdTab() : handleViewChange('editor')} + onSettingsClick={() => view === 'tabs' ? createSettingsTab() : handleViewChange('settings')} + onUsageClick={() => view === 'tabs' ? createUsageTab() : handleViewChange('usage-dashboard')} + onMCPClick={() => view === 'tabs' ? createMCPTab() : handleViewChange('mcp')} onInfoClick={() => setShowNFO(true)} - onAgentsClick={() => setShowAgentsModal(true)} + onAgentsClick={() => view === 'tabs' ? setShowAgentsModal(true) : handleViewChange('cc-agents')} /> {/* Analytics Consent Banner */} {/* Main Content */} -
+
{renderContent()}
diff --git a/src/components/AgentsModal.tsx b/src/components/AgentsModal.tsx index 4eebfd5..f69a3de 100644 --- a/src/components/AgentsModal.tsx +++ b/src/components/AgentsModal.tsx @@ -230,24 +230,24 @@ export const AgentsModal: React.FC = ({ open, onOpenChange })
- From File + {t('agents.importFromFile')} - From GitHub + {t('agents.importFromGitHub')} @@ -268,7 +268,7 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) window.dispatchEvent(new CustomEvent('open-create-agent-tab')); }}> - Create Agent + {t('agents.createAgent')}
) : ( @@ -299,7 +299,7 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) onClick={() => handleExportAgent(agent)} > - Export + {t('agents.export')}
@@ -331,9 +331,9 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) {runningAgents.length === 0 ? (
-

No running agents

+

{t('agents.noRunningAgents')}

- Agent executions will appear here when started + {t('agents.agentExecutionsWillAppear')}

) : ( @@ -373,7 +373,7 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) handleOpenAgentRun(run); }} > - View + {t('agents.view')}
@@ -392,9 +392,9 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) - Delete Agent + {t('agents.deleteAgentTitle')} - Are you sure you want to delete "{agentToDelete?.name}"? This action cannot be undone. + {t('agents.deleteConfirmation', { name: agentToDelete?.name })}
@@ -405,13 +405,13 @@ export const AgentsModal: React.FC = ({ open, onOpenChange }) setAgentToDelete(null); }} > - Cancel + {t('app.cancel')}
diff --git a/src/components/AnalyticsConsent.tsx b/src/components/AnalyticsConsent.tsx index 30a4c11..98e146e 100644 --- a/src/components/AnalyticsConsent.tsx +++ b/src/components/AnalyticsConsent.tsx @@ -72,10 +72,10 @@ export const AnalyticsConsent: React.FC = ({
- {t('analytics.helpImproveClaudia')} + {t('settings.analytics.helpImproveClaudia')} - {t('analytics.collectAnonymousData')} + {t('settings.analytics.collectAnonymousData')} @@ -86,12 +86,12 @@ export const AnalyticsConsent: React.FC = ({
-

{t('analytics.whatWeCollect')}

+

{t('settings.analytics.whatWeCollect')}

    -
  • • {t('analytics.featureUsageDesc')}
  • -
  • • {t('analytics.performanceMetricsDesc')}
  • -
  • • {t('analytics.errorReportsDesc')}
  • -
  • • {t('analytics.usagePatternsDesc')}
  • +
  • • {t('settings.analytics.featureUsageDesc')}
  • +
  • • {t('settings.analytics.performanceMetricsDesc')}
  • +
  • • {t('settings.analytics.errorReportsDesc')}
  • +
  • • {t('settings.analytics.usagePatternsDesc')}
@@ -101,13 +101,13 @@ export const AnalyticsConsent: React.FC = ({
-

{t('analytics.privacyProtected')}

+

{t('settings.analytics.privacyProtected')}

    -
  • • {t('analytics.noPersonalInfo')}
  • -
  • • {t('analytics.noFileContents')}
  • -
  • • {t('analytics.noApiKeys')}
  • -
  • • {t('analytics.anonymousData')}
  • -
  • • {t('analytics.canOptOut')}
  • +
  • • {t('settings.analytics.noPersonalInfo')}
  • +
  • • {t('settings.analytics.noFileContents')}
  • +
  • • {t('settings.analytics.noApiKeys')}
  • +
  • • {t('settings.analytics.anonymousData')}
  • +
  • • {t('settings.analytics.canOptOut')}
@@ -118,7 +118,7 @@ export const AnalyticsConsent: React.FC = ({

- {t('analytics.dataHelpsUs')} + {t('settings.analytics.dataHelpsUs')}

@@ -130,13 +130,13 @@ export const AnalyticsConsent: React.FC = ({ variant="outline" className="flex-1" > - {t('analytics.noThanks')} + {t('settings.analytics.noThanks')} @@ -151,6 +151,7 @@ interface AnalyticsConsentBannerProps { export const AnalyticsConsentBanner: React.FC = ({ className, }) => { + const { t } = useTranslation(); const [visible, setVisible] = useState(false); const [hasChecked, setHasChecked] = useState(false); @@ -199,9 +200,9 @@ export const AnalyticsConsentBanner: React.FC = ({
-

Help improve Claudia

+

{t('settings.analytics.helpImproveClaudia')}

- We collect anonymous usage data to improve your experience. No personal data is collected. + {t('settings.analytics.collectAnonymousData')}

diff --git a/src/components/ClaudeVersionSelector.tsx b/src/components/ClaudeVersionSelector.tsx index 82ea17b..e3ec19a 100644 --- a/src/components/ClaudeVersionSelector.tsx +++ b/src/components/ClaudeVersionSelector.tsx @@ -134,8 +134,8 @@ export const ClaudeVersionSelector: React.FC = ({ return ( - {t('settings.claudeCodeInstallation')} - {t('settings.loadingAvailableInstallations')} + {t('settings.generalOptions.claudeCodeInstallation')} + {t('settings.generalOptions.loadingAvailableInstallations')}
@@ -150,8 +150,8 @@ export const ClaudeVersionSelector: React.FC = ({ return ( - {t('settings.claudeCodeInstallation')} - {t('settings.errorLoadingInstallations')} + {t('settings.generalOptions.claudeCodeInstallation')} + {t('settings.generalOptions.errorLoadingInstallations')}
{error}
@@ -171,19 +171,19 @@ export const ClaudeVersionSelector: React.FC = ({ - {t('settings.claudeCodeInstallation')} + {t('settings.generalOptions.claudeCodeInstallation')} - {t('settings.choosePreferredInstallation')} + {t('settings.generalOptions.choosePreferredInstallation')} {/* Available Installations */}
- +