Skip to content

Commit 5a5bb35

Browse files
authored
refactor(frontend): update sidebar components to use useRouter for na… (#184)
https://jam.dev/c/c3718687-e412-4189-a082-3f3a6687c6fb <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Streamlined sidebar navigation: deleting a chat now smoothly redirects you to the home view. - Enhanced chat selection behavior for more intuitive and responsive transitions. - Added functionality to navigate to a new URL after successfully creating a project. - **Refactor** - Refined sidebar interactions to ensure consistent and seamless updates during chat management. - Improved type safety and internal logic within the ChatRow component. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 9e748e0 commit 5a5bb35

File tree

4 files changed

+37
-39
lines changed

4 files changed

+37
-39
lines changed

frontend/src/app/(main)/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ export default function HomePage() {
3030
if (!message.trim()) return;
3131

3232
try {
33-
await createProjectFromPrompt(message, isPublic, model);
33+
const chatId = await createProjectFromPrompt(message, isPublic, model);
3434
promptFormRef.current.clearMessage();
35+
router.push(`/chat?id=${chatId}`);
3536
} catch (error) {
3637
logger.error('Error creating project:', error);
3738
}

frontend/src/components/chat/code-engine/project-context.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface ProjectContextType {
2828
setProjects: React.Dispatch<React.SetStateAction<Project[]>>;
2929
curProject: Project | undefined;
3030
setCurProject: React.Dispatch<React.SetStateAction<Project | undefined>>;
31-
projectLoading: boolean; // 新增字段
31+
projectLoading: boolean;
3232
filePath: string | null;
3333
setFilePath: React.Dispatch<React.SetStateAction<string | null>>;
3434
createNewProject: (projectName: string, description: string) => Promise<void>;
@@ -404,15 +404,6 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
404404
const [createProject] = useMutation(CREATE_PROJECT, {
405405
onCompleted: (data) => {
406406
if (!isMounted.current) return;
407-
408-
// Navigate to chat page after project creation
409-
if (data?.createProject?.id) {
410-
toast.success('Project created successfully!');
411-
router.push(`/chat?id=${data.createProject.id}`);
412-
413-
// Refresh the projects list
414-
refreshProjects();
415-
}
416407
},
417408
onError: (error) => {
418409
if (isMounted.current) {
@@ -723,8 +714,9 @@ export function ProjectProvider({ children }: { children: ReactNode }) {
723714
},
724715
},
725716
});
717+
console.log('creatae a project result:', result);
726718

727-
return !!result.data?.createProject;
719+
return result.data.id;
728720
} catch (error) {
729721
logger.error('Error creating project:', error);
730722
if (isMounted.current) {

frontend/src/components/sidebar-item.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ function SideBarItemComponent({
4141
}: SideBarItemProps) {
4242
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
4343
const [isDialogOpen, setIsDialogOpen] = useState(false);
44+
const router = useRouter();
4445

4546
const isSelected = currentChatId === id;
4647
const variant = isSelected ? 'secondary' : 'ghost';
@@ -49,7 +50,7 @@ function SideBarItemComponent({
4950
onCompleted: () => {
5051
toast.success('Chat deleted successfully');
5152
if (isSelected) {
52-
window.history.replaceState({}, '', '/');
53+
router.push('/');
5354
const event = new Event(EventEnum.NEW_CHAT);
5455
window.dispatchEvent(event);
5556
}
@@ -77,9 +78,6 @@ function SideBarItemComponent({
7778

7879
const handleChatClick = (e: React.MouseEvent) => {
7980
if (!(e.target as HTMLElement).closest('.dropdown-trigger')) {
80-
window.history.replaceState({}, '', `/chat?id=${id}`);
81-
const event = new Event(EventEnum.CHAT);
82-
window.dispatchEvent(event);
8381
onSelect(id);
8482
}
8583
};

frontend/src/components/sidebar.tsx

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
'use client';
2-
32
import { Button } from '@/components/ui/button';
43
import Image from 'next/image';
54
import { memo, useCallback, useContext, useState } from 'react';
@@ -9,7 +8,7 @@ import { SideBarItem } from './sidebar-item';
98
import { Chat } from '@/graphql/type';
109
import { EventEnum } from '../const/EventEnum';
1110
import { useRouter } from 'next/navigation';
12-
import { FixedSizeList } from 'react-window';
11+
import { FixedSizeList, ListChildComponentProps } from 'react-window';
1312

1413
import {
1514
SidebarContent,
@@ -36,37 +35,41 @@ interface SidebarProps {
3635
setChatListUpdated: (value: boolean) => void;
3736
chats: Chat[];
3837
loading: boolean;
39-
error: any;
38+
error: unknown;
39+
onRefetch: () => void;
40+
}
41+
42+
interface ChatRowData {
43+
chats: Chat[];
44+
currentChatId: string;
45+
onSelect: (chatId: string) => void;
4046
onRefetch: () => void;
4147
}
4248

49+
interface ChatRowProps extends ListChildComponentProps {
50+
data: ChatRowData;
51+
}
52+
4353
// Row renderer for react-window
4454
const ChatRow = memo(
45-
({ index, style, data }: any) => {
46-
const { chats, currentChatId, setCurProject, pollChatProject } = data;
55+
({ index, style, data }: ChatRowProps) => {
56+
const { onSelect, chats, currentChatId, onRefetch } = data;
4757
const chat = chats[index];
4858

49-
const handleSelect = useCallback(() => {
50-
setCurProject(null);
51-
pollChatProject(chat.id).then((p) => {
52-
setCurProject(p);
53-
});
54-
}, [chat.id, setCurProject, pollChatProject]);
55-
5659
return (
5760
<div style={style}>
5861
<SideBarItem
5962
key={chat.id}
6063
id={chat.id}
6164
currentChatId={currentChatId}
6265
title={chat.title}
63-
onSelect={handleSelect}
64-
refetchChats={data.onRefetch}
66+
onSelect={() => onSelect(chat.id)}
67+
refetchChats={onRefetch}
6568
/>
6669
</div>
6770
);
6871
},
69-
(prevProps, nextProps) => {
72+
(prevProps: ChatRowProps, nextProps: ChatRowProps) => {
7073
return (
7174
prevProps.data.chats[prevProps.index].id ===
7275
nextProps.data.chats[nextProps.index].id &&
@@ -91,18 +94,24 @@ function ChatSideBarComponent({
9194
const { setCurProject, pollChatProject } = useContext(ProjectContext);
9295

9396
const handleNewChat = useCallback(() => {
94-
window.history.replaceState({}, '', '/');
97+
router.push('/');
9598
setCurrentChatid('');
9699
const event = new Event(EventEnum.NEW_CHAT);
97100
window.dispatchEvent(event);
98-
}, []);
101+
}, [router]);
99102

100103
const handleChatSelect = useCallback(
101104
(chatId: string) => {
102-
router.push(`/chat?id=${chatId}`);
103105
setCurrentChatid(chatId);
106+
router.push(`/chat?id=${chatId}`);
107+
setCurProject(null);
108+
pollChatProject(chatId).then((p) => {
109+
setCurProject(p);
110+
});
111+
const event = new Event(EventEnum.CHAT);
112+
window.dispatchEvent(event);
104113
},
105-
[router]
114+
[router, setCurProject, pollChatProject]
106115
);
107116

108117
if (loading) return <SidebarSkeleton />;
@@ -215,10 +224,8 @@ function ChatSideBarComponent({
215224
itemData={{
216225
chats,
217226
currentChatId: currentChatid,
218-
setCurProject,
219-
pollChatProject,
220-
onRefetch,
221227
onSelect: handleChatSelect,
228+
onRefetch,
222229
}}
223230
>
224231
{ChatRow}
@@ -247,7 +254,7 @@ function ChatSideBarComponent({
247254
// Optimized memo comparison
248255
export const ChatSideBar = memo(
249256
ChatSideBarComponent,
250-
(prevProps, nextProps) => {
257+
(prevProps: SidebarProps, nextProps: SidebarProps) => {
251258
if (prevProps.isCollapsed !== nextProps.isCollapsed) return false;
252259
if (prevProps.loading !== nextProps.loading) return false;
253260
if (prevProps.error !== nextProps.error) return false;

0 commit comments

Comments
 (0)