Skip to content

Commit 845c365

Browse files
committed
UI updates, splitview, lucide icons, fast chat switching
add split view for switching chats remove emoji in favour of lucide icons Fast switch chats Updated responsiveness of project list
1 parent 7f3850c commit 845c365

15 files changed

Lines changed: 1349 additions & 37 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ backend/dist/
99
frontend/demo-recordings/
1010
frontend/test-results/
1111
frontend/playwright-report/
12-
frontend/playwright/.cache/
12+
frontend/playwright/.cache/
13+
.env

backend/deno.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"dependencies": {
2424
"@heroicons/react": "^2.2.0",
2525
"dayjs": "^1.11.13",
26+
"lucide-react": "^0.544.0",
2627
"react": "^19.1.0",
2728
"react-dom": "^19.1.1",
2829
"react-router-dom": "^7.6.2"

frontend/src/App.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
22
import { Suspense, lazy } from "react";
3-
import { ProjectSelector } from "./components/ProjectSelector";
4-
import { ChatPage } from "./components/ChatPage";
3+
import { SplitView } from "./components/SplitView";
54
import { SettingsProvider } from "./contexts/SettingsContext";
65
import { isDevelopment } from "./utils/environment";
76

@@ -19,8 +18,7 @@ function App() {
1918
<SettingsProvider>
2019
<Router>
2120
<Routes>
22-
<Route path="/" element={<ProjectSelector />} />
23-
<Route path="/projects/*" element={<ChatPage />} />
21+
<Route path="/" element={<SplitView />} />
2422
{DemoPage && (
2523
<Route
2624
path="/demo"

frontend/src/components/ChatPage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,15 @@ export function ChatPage() {
439439
{/* Header */}
440440
<div className="flex items-center justify-between mb-4 sm:mb-8 flex-shrink-0">
441441
<div className="flex items-center gap-4">
442+
{!isHistoryView && !isLoadedConversation && (
443+
<button
444+
onClick={handleBackToProjects}
445+
className="p-2 rounded-lg bg-white/80 dark:bg-slate-800/80 border border-slate-200 dark:border-slate-700 hover:bg-white dark:hover:bg-slate-800 transition-all duration-200 backdrop-blur-sm shadow-sm hover:shadow-md"
446+
aria-label="Back to project selection"
447+
>
448+
<ChevronLeftIcon className="w-5 h-5 text-slate-600 dark:text-slate-400" />
449+
</button>
450+
)}
442451
{isHistoryView && (
443452
<button
444453
onClick={handleBackToChat}

frontend/src/components/MessageComponents.tsx

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ import {
2020
isEditToolUseResult,
2121
isBashToolUseResult,
2222
} from "../utils/contentUtils";
23+
import {
24+
Settings,
25+
Wrench,
26+
CheckCircle,
27+
ClipboardList,
28+
Brain,
29+
Clock,
30+
CheckCheck,
31+
RotateCcw,
32+
Loader,
33+
MessageSquare,
34+
} from "lucide-react";
2335

2436
// ANSI escape sequence regex for cleaning hooks messages
2537
const ANSI_REGEX = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
@@ -66,7 +78,7 @@ export function ChatMessageComponent({ message }: ChatMessageComponentProps) {
6678
}`}
6779
/>
6880
</div>
69-
<pre className="whitespace-pre-wrap text-sm font-mono leading-relaxed">
81+
<pre className="whitespace-pre-wrap break-words overflow-x-auto text-sm font-mono leading-relaxed">
7082
{message.content}
7183
</pre>
7284
</MessageContainer>
@@ -127,7 +139,7 @@ export function SystemMessageComponent({
127139
label={getLabel()}
128140
details={details}
129141
badge={"subtype" in message ? message.subtype : undefined}
130-
icon={<span className="bg-blue-400 dark:bg-blue-500"></span>}
142+
icon={<Settings className="w-4 h-4 text-white" />}
131143
colorScheme={{
132144
header: "text-blue-800 dark:text-blue-300",
133145
content: "text-blue-700 dark:text-blue-300",
@@ -150,7 +162,7 @@ export function ToolMessageComponent({ message }: ToolMessageComponentProps) {
150162
>
151163
<div className="text-xs font-semibold mb-2 opacity-90 text-emerald-700 dark:text-emerald-300 flex items-center gap-2">
152164
<div className="w-4 h-4 bg-emerald-500 dark:bg-emerald-600 rounded-full flex items-center justify-center text-white text-xs">
153-
🔧
165+
<Wrench className="w-3 h-3" />
154166
</div>
155167
{message.content}
156168
</div>
@@ -221,7 +233,7 @@ export function ToolResultMessageComponent({
221233
label={message.toolName}
222234
details={displayContent}
223235
badge={message.toolName === "Edit" ? undefined : message.summary}
224-
icon={<span className="bg-emerald-400 dark:bg-emerald-500"></span>}
236+
icon={<CheckCircle className="w-4 h-4 text-white" />}
225237
colorScheme={{
226238
header: "text-emerald-800 dark:text-emerald-300",
227239
content: "text-emerald-700 dark:text-emerald-300",
@@ -250,7 +262,7 @@ export function PlanMessageComponent({ message }: PlanMessageComponentProps) {
250262
<div className="mb-3 flex items-center justify-between gap-4">
251263
<div className="text-xs font-semibold opacity-90 text-blue-700 dark:text-blue-300 flex items-center gap-2">
252264
<div className="w-4 h-4 bg-blue-500 dark:bg-blue-600 rounded-full flex items-center justify-center text-white text-xs">
253-
📋
265+
<ClipboardList className="w-3 h-3" />
254266
</div>
255267
Ready to code?
256268
</div>
@@ -265,7 +277,7 @@ export function PlanMessageComponent({ message }: PlanMessageComponentProps) {
265277
Here is Claude's plan:
266278
</p>
267279
<div className="bg-blue-100/50 dark:bg-blue-800/30 border border-blue-200 dark:border-blue-700 rounded-lg p-3">
268-
<pre className="text-sm text-blue-900 dark:text-blue-100 whitespace-pre-wrap font-mono leading-relaxed">
280+
<pre className="text-sm text-blue-900 dark:text-blue-100 whitespace-pre-wrap break-words overflow-x-auto font-mono leading-relaxed">
269281
{message.plan}
270282
</pre>
271283
</div>
@@ -286,7 +298,7 @@ export function ThinkingMessageComponent({
286298
label="Claude's Reasoning"
287299
details={message.content}
288300
badge="thinking"
289-
icon={<span className="bg-purple-400 dark:bg-purple-500">💭</span>}
301+
icon={<Brain className="w-4 h-4 text-white" />}
290302
colorScheme={{
291303
header: "text-purple-700 dark:text-purple-300",
292304
content: "text-purple-600 dark:text-purple-400 italic",
@@ -306,12 +318,15 @@ export function TodoMessageComponent({ message }: TodoMessageComponentProps) {
306318
const getStatusIcon = (status: TodoItem["status"]) => {
307319
switch (status) {
308320
case "completed":
309-
return { icon: "✅", label: "Completed" };
321+
return { icon: <CheckCheck className="w-4 h-4" />, label: "Completed" };
310322
case "in_progress":
311-
return { icon: "🔄", label: "In progress" };
323+
return {
324+
icon: <RotateCcw className="w-4 h-4" />,
325+
label: "In progress",
326+
};
312327
case "pending":
313328
default:
314-
return { icon: "⏳", label: "Pending" };
329+
return { icon: <Clock className="w-4 h-4" />, label: "Pending" };
315330
}
316331
};
317332

@@ -338,7 +353,7 @@ export function TodoMessageComponent({ message }: TodoMessageComponentProps) {
338353
className="w-4 h-4 bg-amber-500 dark:bg-amber-600 rounded-full flex items-center justify-center text-white text-xs"
339354
aria-hidden="true"
340355
>
341-
📋
356+
<ClipboardList className="w-3 h-3" />
342357
</div>
343358
Todo List Updated
344359
</div>
@@ -353,12 +368,12 @@ export function TodoMessageComponent({ message }: TodoMessageComponentProps) {
353368
const statusIcon = getStatusIcon(todo.status);
354369
return (
355370
<div key={index} className="flex items-start gap-2">
356-
<span
357-
className="text-sm flex-shrink-0 mt-0.5"
371+
<div
372+
className="flex-shrink-0 mt-0.5"
358373
aria-label={statusIcon.label}
359374
>
360375
{statusIcon.icon}
361-
</span>
376+
</div>
362377
<div className="flex-1 min-w-0">
363378
<div className={`text-sm ${getStatusColor(todo.status)}`}>
364379
{todo.content}
@@ -392,7 +407,7 @@ export function LoadingComponent() {
392407
Claude
393408
</div>
394409
<div className="flex items-center gap-2 text-sm">
395-
<div className="w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"></div>
410+
<Loader className="w-4 h-4 animate-spin" />
396411
<span className="animate-pulse">Thinking...</span>
397412
</div>
398413
</MessageContainer>

0 commit comments

Comments
 (0)