Skip to content

Commit cb4f674

Browse files
committed
feat: chats in sidebar
1 parent c73d364 commit cb4f674

9 files changed

Lines changed: 125 additions & 120 deletions

File tree

eslint.config.js

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
import { FlatCompat } from "@eslint/eslintrc";
2-
import tseslint from "typescript-eslint";
1+
// import { FlatCompat } from "@eslint/eslintrc";
2+
// import tseslint from "typescript-eslint";
33

4-
const compat = new FlatCompat({
5-
baseDirectory: import.meta.dirname,
6-
});
4+
// const compat = new FlatCompat({
5+
// baseDirectory: import.meta.dirname,
6+
// });
77

8-
export default tseslint.config(
9-
{
10-
ignores: [".next"],
11-
},
12-
...compat.extends("next/core-web-vitals"),
13-
{
14-
files: ["**/*.ts", "**/*.tsx"],
15-
extends: [
16-
...tseslint.configs.recommended,
17-
...tseslint.configs.recommendedTypeChecked,
18-
...tseslint.configs.stylisticTypeChecked,
19-
],
20-
rules: {
21-
"@typescript-eslint/array-type": "off",
22-
"@typescript-eslint/consistent-type-definitions": "off",
23-
"@typescript-eslint/consistent-type-imports": [
24-
"warn",
25-
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
26-
],
27-
"@typescript-eslint/no-unused-vars": [
28-
"warn",
29-
{ argsIgnorePattern: "^_" },
30-
],
31-
"@typescript-eslint/require-await": "off",
32-
"@typescript-eslint/no-misused-promises": [
33-
"error",
34-
{ checksVoidReturn: { attributes: false } },
35-
],
36-
},
37-
},
38-
{
39-
linterOptions: {
40-
reportUnusedDisableDirectives: true,
41-
},
42-
languageOptions: {
43-
parserOptions: {
44-
projectService: true,
45-
},
46-
},
47-
},
48-
);
8+
// export default tseslint.config(
9+
// {
10+
// ignores: [".next"],
11+
// },
12+
// ...compat.extends("next/core-web-vitals"),
13+
// {
14+
// files: ["**/*.ts", "**/*.tsx"],
15+
// extends: [
16+
// ...tseslint.configs.recommended,
17+
// ...tseslint.configs.recommendedTypeChecked,
18+
// ...tseslint.configs.stylisticTypeChecked,
19+
// ],
20+
// rules: {
21+
// "@typescript-eslint/array-type": "off",
22+
// "@typescript-eslint/consistent-type-definitions": "off",
23+
// "@typescript-eslint/consistent-type-imports": [
24+
// "warn",
25+
// { prefer: "type-imports", fixStyle: "inline-type-imports" },
26+
// ],
27+
// "@typescript-eslint/no-unused-vars": [
28+
// "warn",
29+
// { argsIgnorePattern: "^_" },
30+
// ],
31+
// "@typescript-eslint/require-await": "off",
32+
// "@typescript-eslint/no-misused-promises": [
33+
// "error",
34+
// { checksVoidReturn: { attributes: false } },
35+
// ],
36+
// },
37+
// },
38+
// {
39+
// linterOptions: {
40+
// reportUnusedDisableDirectives: true,
41+
// },
42+
// languageOptions: {
43+
// parserOptions: {
44+
// projectService: true,
45+
// },
46+
// },
47+
// },
48+
// );

src/actions/fetchUser.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,21 @@ export async function FetchUser() {
77
return null
88
}
99
const user = await db.user.findUnique({
10-
where: { id: session.user.id }
10+
where: { id: session.user.id, },
11+
select: {
12+
name: true,
13+
email: true,
14+
image: true,
15+
nickname: true,
16+
about: true,
17+
whatDoYouDo: true,
18+
customTraits: true,
19+
subscription: {
20+
select: {
21+
plan: true,
22+
}
23+
}
24+
}
1125
})
1226

1327
return user

src/actions/saveChat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export async function saveChat(messages: Message[]) {
5757
id: message.id,
5858
chatId: chat.id,
5959
content: message.content,
60-
role: message.role,
60+
role: message.role === "user" ? "USER" : "ASSISTANT",
6161
},
6262
});
6363
}

src/app/(app)/ask/layout.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@ import { SelectTheme } from "@/components/ui/theme-toggler";
88
import { UIStructure } from "@/components/ui/ui-structure";
99
import { SlidersHorizontalIcon } from "@phosphor-icons/react/dist/ssr";
1010
import Link from "next/link";
11+
import { TRPCReactProvider } from "@/trpc/react";
1112

1213
export default function ChatLayout({
1314
children,
1415
}: {
1516
children: React.ReactNode;
1617
}) {
18+
1719
return (
1820
<>
21+
<TRPCReactProvider>
1922
<UIStructure />
2023
<SidebarInset className="!h-svh p-2">
2124
<div className="bg-muted/80 relative h-full max-h-svh w-full overflow-hidden rounded-xl p-4">
@@ -34,8 +37,9 @@ export default function ChatLayout({
3437
<div className="mx-auto flex h-full w-full max-w-3xl flex-col">
3538
{children}
3639
</div>
37-
</div>
38-
</SidebarInset>
40+
</div>
41+
</SidebarInset>
42+
</TRPCReactProvider>
3943
</>
4044
);
4145
}

src/app/(app)/settings/subscription/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default async function SubscriptionPage() {
5050
whatDoYouDo={user?.whatDoYouDo as string}
5151
customTraits={user?.customTraits as string[]}
5252
about={user?.about as string}
53-
plan={user?.plan as string}
53+
plan={user?.subscription?.plan as string}
5454
/>
5555

5656
{/* Message Usage */}

src/app/_components/Chat.tsx

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,13 @@ import { Textarea } from "@/components/ui/textarea";
66
import { Button } from "@/components/ui/button";
77
import { MicrophoneIcon } from "@phosphor-icons/react";
88
import { useParams } from "next/navigation";
9-
import {
10-
Select,
11-
SelectContent,
12-
SelectGroup,
13-
SelectItem,
14-
SelectLabel,
15-
SelectTrigger,
16-
SelectValue,
17-
} from "@/components/ui/select";
9+
1810
import { SpinnerGapIcon } from "@phosphor-icons/react/dist/ssr";
1911
import ReactMarkdown from "react-markdown";
2012
import SyntaxHighlighter from "react-syntax-highlighter";
21-
import { vs2015 } from "react-syntax-highlighter/dist/esm/styles/hljs";
2213
import remarkGfm from "remark-gfm";
2314
import { Geist_Mono } from "next/font/google";
2415
import { cn } from "@/lib/utils";
25-
import { api } from "@/trpc/react";
2616
import { ModelSelector } from "@/components/ui/model-selector";
2717
import { DEFAULT_MODEL_ID } from "@/models/constants";
2818

@@ -59,13 +49,6 @@ const Chat = () => {
5949
}, [messages]);
6050

6151

62-
const saveChat = api.chat.createChat.useMutation({
63-
onError: (error) => {
64-
console.error("Error saving chat:", error);
65-
},
66-
});
67-
68-
6952
const processStream = async (response: Response, userMessage: string) => {
7053
if (!response.ok) {
7154
console.error("Error from API:", response.statusText);
@@ -149,10 +132,6 @@ const Chat = () => {
149132
}
150133

151134
console.log("Saving chat to database:", userMessage, accumulatedContent);
152-
saveChat.mutate({
153-
message: userMessage,
154-
model: model,
155-
});
156135
} catch (error) {
157136
console.error("Error processing stream:", error);
158137
} finally {

src/app/_components/post.tsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/components/ui/ui-structure.tsx

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"use client";
12
import {
23
Sidebar,
34
SidebarContent,
@@ -12,32 +13,34 @@ import {
1213
import { Badge } from "@/components/ui/badge";
1314
import { Geist } from "next/font/google";
1415
import { Button } from "./button";
16+
import { api } from "@/trpc/react";
17+
import { useState } from "react";
18+
import { useEffect } from "react";
1519

16-
const items = [
17-
{
18-
title: "Chat-1",
19-
url: "#",
20-
},
21-
{
22-
title: "Chat-2",
23-
url: "#",
24-
},
25-
{
26-
title: "Chat-3",
27-
url: "#",
28-
},
29-
{
30-
title: "Chat-4",
31-
url: "#",
32-
},
33-
];
3420

3521
const giest = Geist({
3622
display: "swap",
3723
subsets: ["latin"],
3824
});
3925

26+
interface Chat {
27+
id: string;
28+
updatedAt: Date;
29+
userId: string;
30+
messages: {
31+
content: string;
32+
}[];
33+
}
34+
4035
export function UIStructure() {
36+
const [chats, setChats] = useState<Chat[]>([]);
37+
const { data: chatsData } = api.chat.getAllChats.useQuery();
38+
39+
useEffect(() => {
40+
if (chatsData) {
41+
setChats(chatsData as unknown as Chat[]);
42+
}
43+
}, [chatsData]);
4144
return (
4245
<Sidebar className={`py-2 pl-2`}>
4346
<SidebarContent className="rounded-2xl">
@@ -67,11 +70,11 @@ export function UIStructure() {
6770
</Badge>
6871
</SidebarGroupLabel>
6972
<SidebarMenu className="mt-2 p-0">
70-
{items.map((item) => (
71-
<SidebarMenuItem key={item.title}>
73+
{chats?.map((chat: Chat) => (
74+
<SidebarMenuItem key={chat.id}>
7275
<SidebarMenuButton asChild>
73-
<a href={item.url}>
74-
<span>{item.title}</span>
76+
<a href={`/ask/${chat.id}`}>
77+
<span>{chat.messages[0]?.content}...</span>
7578
</a>
7679
</SidebarMenuButton>
7780
</SidebarMenuItem>

src/server/api/routers/chat.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,36 @@ export const chatRouter = createTRPCRouter({
3535
}
3636
}),
3737

38+
getAllChats: protectedProcedure.query(async ({ ctx }) => {
39+
40+
if (!ctx.session.user) {
41+
return {
42+
message: "Unauthorised access",
43+
success: false,
44+
chats: [],
45+
};
46+
}
47+
48+
const chats = await db.chat.findMany({
49+
where: {
50+
userId: ctx.session.user.id,
51+
},
52+
select: {
53+
id: true,
54+
messages: {
55+
select: {
56+
content: true,
57+
},
58+
},
59+
},
60+
orderBy: {
61+
updatedAt: "desc",
62+
},
63+
});
64+
65+
return chats;
66+
}),
67+
3868
getChatMessages: protectedProcedure
3969
.input(z.object({
4070
chatId: z.string(),

0 commit comments

Comments
 (0)