Skip to content

Commit 3749f91

Browse files
committed
Revert "site: remove chat-related changes for separate PR"
This reverts commit cd76201.
1 parent 54a20db commit 3749f91

File tree

13 files changed

+3436
-0
lines changed

13 files changed

+3436
-0
lines changed

site/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
"update-emojis": "cp -rf ./node_modules/emoji-datasource-apple/img/apple/64/* ./static/emojis"
3636
},
3737
"dependencies": {
38+
"@ai-sdk/provider-utils": "2.2.6",
39+
"@ai-sdk/react": "1.2.6",
40+
"@ai-sdk/ui-utils": "1.2.7",
3841
"@emoji-mart/data": "1.2.1",
3942
"@emoji-mart/react": "1.1.1",
4043
"@emotion/cache": "11.14.0",
@@ -111,6 +114,7 @@
111114
"react-virtualized-auto-sizer": "1.0.24",
112115
"react-window": "1.8.11",
113116
"recharts": "2.15.0",
117+
"rehype-raw": "7.0.0",
114118
"remark-gfm": "4.0.0",
115119
"resize-observer-polyfill": "1.5.1",
116120
"rollup-plugin-visualizer": "5.14.0",

site/pnpm-lock.yaml

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

site/src/api/api.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,13 @@ class ApiMethods {
827827
return response.data;
828828
};
829829

830+
getDeploymentLLMs = async (): Promise<TypesGen.LanguageModelConfig> => {
831+
const response = await this.axios.get<TypesGen.LanguageModelConfig>(
832+
"/api/v2/deployment/llms",
833+
);
834+
return response.data;
835+
};
836+
830837
getOrganizationIdpSyncClaimFieldValues = async (
831838
organization: string,
832839
field: string,
@@ -2489,6 +2496,23 @@ class ApiMethods {
24892496
markAllInboxNotificationsAsRead = async () => {
24902497
await this.axios.put<void>("/api/v2/notifications/inbox/mark-all-as-read");
24912498
};
2499+
2500+
createChat = async () => {
2501+
const res = await this.axios.post<TypesGen.Chat>("/api/v2/chats");
2502+
return res.data;
2503+
};
2504+
2505+
getChats = async () => {
2506+
const res = await this.axios.get<TypesGen.Chat[]>("/api/v2/chats");
2507+
return res.data;
2508+
};
2509+
2510+
getChatMessages = async (chatId: string) => {
2511+
const res = await this.axios.get<TypesGen.ChatMessage[]>(
2512+
`/api/v2/chats/${chatId}/messages`,
2513+
);
2514+
return res.data;
2515+
};
24922516
}
24932517

24942518
// This is a hard coded CSRF token/cookie pair for local development. In prod,

site/src/api/queries/chats.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { API } from "api/api";
2+
import type { QueryClient } from "react-query";
3+
4+
export const createChat = (queryClient: QueryClient) => {
5+
return {
6+
mutationFn: API.createChat,
7+
onSuccess: async () => {
8+
await queryClient.invalidateQueries(["chats"]);
9+
},
10+
};
11+
};
12+
13+
export const getChats = () => {
14+
return {
15+
queryKey: ["chats"],
16+
queryFn: API.getChats,
17+
};
18+
};
19+
20+
export const getChatMessages = (chatID: string) => {
21+
return {
22+
queryKey: ["chatMessages", chatID],
23+
queryFn: () => API.getChatMessages(chatID),
24+
};
25+
};

site/src/api/queries/deployment.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ export const deploymentIdpSyncFieldValues = (field: string) => {
3636
queryFn: () => API.getDeploymentIdpSyncFieldValues(field),
3737
};
3838
};
39+
40+
export const deploymentLanguageModels = () => {
41+
return {
42+
queryKey: ["deployment", "llms"],
43+
queryFn: API.getDeploymentLLMs,
44+
};
45+
};

site/src/modules/dashboard/Navbar/NavbarView.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ const NavItems: FC<NavItemsProps> = ({ className }) => {
154154
>
155155
Templates
156156
</NavLink>
157+
<NavLink
158+
className={({ isActive }) => {
159+
return cn(linkStyles.default, isActive ? linkStyles.active : "");
160+
}}
161+
to="/chat"
162+
>
163+
Chat
164+
</NavLink>
157165
</nav>
158166
);
159167
};
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import { useTheme } from "@emotion/react";
2+
import SendIcon from "@mui/icons-material/Send";
3+
import Button from "@mui/material/Button";
4+
import IconButton from "@mui/material/IconButton";
5+
import Paper from "@mui/material/Paper";
6+
import Stack from "@mui/material/Stack";
7+
import TextField from "@mui/material/TextField";
8+
import { createChat } from "api/queries/chats";
9+
import type { Chat } from "api/typesGenerated";
10+
import { Margins } from "components/Margins/Margins";
11+
import { useAuthenticated } from "contexts/auth/RequireAuth";
12+
import { type FC, type FormEvent, useState } from "react";
13+
import { useMutation, useQueryClient } from "react-query";
14+
import { useNavigate } from "react-router-dom";
15+
import { LanguageModelSelector } from "./LanguageModelSelector";
16+
17+
export interface ChatLandingLocationState {
18+
chat: Chat;
19+
message: string;
20+
}
21+
22+
export const ChatLanding: FC = () => {
23+
const { user } = useAuthenticated();
24+
const theme = useTheme();
25+
const [input, setInput] = useState("");
26+
const navigate = useNavigate();
27+
const queryClient = useQueryClient();
28+
const createChatMutation = useMutation(createChat(queryClient));
29+
30+
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
31+
setInput(event.target.value);
32+
};
33+
34+
// Placeholder submit handler
35+
const handleFormSubmit = (e: FormEvent<HTMLFormElement>) => {
36+
e.preventDefault();
37+
if (!input.trim()) return;
38+
console.log("Form submitted with input:", input);
39+
// Actual submission logic will go elsewhere
40+
setInput(""); // Clear input after submit (optional)
41+
42+
createChatMutation.mutateAsync().then((chat) => {
43+
navigate(`/chat/${chat.id}`, {
44+
state: {
45+
chat,
46+
message: input,
47+
},
48+
});
49+
});
50+
};
51+
52+
// Placeholder suggestion handler
53+
const handleSuggestionClick = (suggestion: string) => {
54+
setInput(suggestion);
55+
// Optionally trigger focus on the input field here
56+
};
57+
58+
return (
59+
<Margins>
60+
<div
61+
css={{
62+
display: "flex",
63+
flexDirection: "column",
64+
marginTop: theme.spacing(24),
65+
alignItems: "center",
66+
paddingBottom: theme.spacing(4),
67+
}}
68+
>
69+
{/* Initial Welcome Message Area */}
70+
<div
71+
css={{
72+
flexGrow: 1,
73+
display: "flex",
74+
flexDirection: "column",
75+
justifyContent: "center",
76+
alignItems: "center",
77+
gap: theme.spacing(1),
78+
padding: theme.spacing(1),
79+
width: "100%",
80+
maxWidth: "700px",
81+
marginBottom: theme.spacing(4),
82+
}}
83+
>
84+
<h1
85+
css={{
86+
fontSize: theme.typography.h4.fontSize,
87+
fontWeight: theme.typography.h4.fontWeight,
88+
lineHeight: theme.typography.h4.lineHeight,
89+
marginBottom: theme.spacing(1),
90+
textAlign: "center",
91+
}}
92+
>
93+
Good evening, {user?.name.split(" ")[0]}
94+
</h1>
95+
<p
96+
css={{
97+
fontSize: theme.typography.h6.fontSize,
98+
fontWeight: theme.typography.h6.fontWeight,
99+
lineHeight: theme.typography.h6.lineHeight,
100+
color: theme.palette.text.secondary,
101+
textAlign: "center",
102+
margin: 0,
103+
maxWidth: "500px",
104+
marginInline: "auto",
105+
}}
106+
>
107+
How can I help you today?
108+
</p>
109+
</div>
110+
111+
{/* Input Form and Suggestions - Always Visible */}
112+
<div css={{ width: "100%", maxWidth: "700px", marginTop: "auto" }}>
113+
<Stack
114+
direction="row"
115+
spacing={2}
116+
justifyContent="center"
117+
sx={{ mb: 2 }}
118+
>
119+
<Button
120+
variant="outlined"
121+
onClick={() =>
122+
handleSuggestionClick("Help me work on issue #...")
123+
}
124+
>
125+
Work on Issue
126+
</Button>
127+
<Button
128+
variant="outlined"
129+
onClick={() =>
130+
handleSuggestionClick("Help me build a template for...")
131+
}
132+
>
133+
Build a Template
134+
</Button>
135+
<Button
136+
variant="outlined"
137+
onClick={() =>
138+
handleSuggestionClick("Help me start a new project using...")
139+
}
140+
>
141+
Start a Project
142+
</Button>
143+
</Stack>
144+
<LanguageModelSelector />
145+
<Paper
146+
component="form"
147+
onSubmit={handleFormSubmit}
148+
elevation={2}
149+
css={{
150+
padding: "16px",
151+
display: "flex",
152+
alignItems: "center",
153+
width: "100%",
154+
borderRadius: "12px",
155+
border: `1px solid ${theme.palette.divider}`,
156+
}}
157+
>
158+
<TextField
159+
value={input}
160+
onChange={handleInputChange}
161+
placeholder="Ask Coder..."
162+
fullWidth
163+
variant="outlined"
164+
multiline
165+
maxRows={5}
166+
css={{
167+
marginRight: theme.spacing(1),
168+
"& .MuiOutlinedInput-root": {
169+
borderRadius: "8px",
170+
padding: "10px 14px",
171+
},
172+
}}
173+
autoFocus
174+
/>
175+
<IconButton type="submit" color="primary" disabled={!input.trim()}>
176+
<SendIcon />
177+
</IconButton>
178+
</Paper>
179+
</div>
180+
</div>
181+
</Margins>
182+
);
183+
};
184+
185+
export default ChatLanding;

0 commit comments

Comments
 (0)