Skip to content

Commit bdc1d32

Browse files
abstracting logic
1 parent 55daffa commit bdc1d32

File tree

11 files changed

+163
-56
lines changed

11 files changed

+163
-56
lines changed

src/app/api/chat/route.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
3+
export async function POST(request: NextRequest) {
4+
// const { uuid, message } = await request.json();
5+
// if (!uuid || !message) {
6+
// return NextResponse.json({ message: "Invalid request" }, { status: 400 });
7+
// }
8+
console.log(request);
9+
return NextResponse.json({ success: true });
10+
}

src/app/chat/[chatId]/page.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ export default function ChatPage() {
3232
}
3333
}, [messages]);
3434

35+
// useEffect(() => {
36+
// const fetchChat = async (chatId: string) => {
37+
// const response = await fetch(`/api/chat/${chatId}`);
38+
// if (!response.ok) {
39+
// notFound();
40+
// return;
41+
// }
42+
// const data = await response.json();
43+
// setMessages(data.messages);
44+
// };
45+
// fetchChat(chatId);
46+
// }, [chatId]);
47+
3548
// TODO: Figure out which models become active and when
3649
// const displayToast = async () => {
3750
// const activeModels = await fetchActiveModels();

src/app/components/InitialChatPage.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
'use client';
2-
31
import ChatMenuNavbar from './chat/ChatMenuNavbar';
42
import ChatHeader from './chat/ChatHeader';
53
import InputField from './InputField';
@@ -12,11 +10,26 @@ export default function InitialChatPage() {
1210
const firstName = user!.displayName!.split(' ')[0];
1311
const router = useRouter();
1412

15-
const handleInitialSendMessage = (message: string) => {
16-
// TODO: Add the chat and message to the database
13+
const createChat = async (uuid: string, message: string) => {
14+
const response = await fetch('/api/chat', {
15+
method: 'POST',
16+
headers: {
17+
'Content-Type': 'application/json',
18+
},
19+
body: JSON.stringify({
20+
uuid,
21+
message,
22+
}),
23+
});
24+
25+
if (!response.ok) {
26+
throw new Error('Failed to create chat');
27+
}
28+
};
29+
30+
const handleInitialSendMessage = async (message: string) => {
1731
const chatId = uuidv4();
18-
// Delete, needed for linter
19-
console.log(`Message: ${message}`);
32+
await createChat(chatId, message);
2033
router.push(`/chat/${chatId}`);
2134
};
2235

@@ -34,7 +47,7 @@ export default function InitialChatPage() {
3447
</div>
3548

3649
<div className="mb-10">
37-
<InputField messageStreaming={false} onSubmit={handleInitialSendMessage} />
50+
<InputField onSubmit={handleInitialSendMessage} messageStreaming={false} />
3851
</div>
3952
</div>
4053
</div>

src/app/components/Protected.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { ReactNode, useEffect } from 'react';
22
import { useAuth } from '@/contexts/AuthContext';
33
import { useRouter } from 'next/navigation';
4-
import Spinner from './Spinner';
54

65
interface ProtectedProps {
76
children: ReactNode;
@@ -17,13 +16,5 @@ export default function Protected({ children }: ProtectedProps) {
1716
}
1817
}, [user, loading, router]);
1918

20-
if (loading) {
21-
return (
22-
<div className="flex h-screen w-screen justify-center align-middle">
23-
<Spinner width="5" height="5" />
24-
</div>
25-
);
26-
}
27-
2819
return <>{user ? children : <></>}</>;
2920
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Chat } from '@/types/chat';
2+
3+
interface ChatHistoryEntryProps {
4+
chat: Chat;
5+
}
6+
7+
export default function ChatHistoryEntry({ chat }: ChatHistoryEntryProps) {
8+
return (
9+
<div className="no-scrollbar mt-5 flex-1 flex-col justify-start overflow-y-auto">
10+
<div key={chat.id} className="m-auto flex w-11/12 flex-row justify-between p-3">
11+
<div className="flex flex-row gap-2">
12+
{/* <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6 text-white">
13+
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 0 1 1.037-.443 48.282 48.282 0 0 0 5.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
14+
</svg> */}
15+
<span className="text-sm text-white">{chat.summary}</span>
16+
</div>
17+
{/* <div>
18+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="size-6 text-white">
19+
<path strokeLinecap="round" strokeLinejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
20+
</svg>
21+
</div> */}
22+
</div>
23+
</div>
24+
);
25+
}

src/app/components/chat/ChatMenu.tsx

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

src/app/components/chat/ChatMenuNavbar.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { useAuth } from '@/contexts/AuthContext';
2-
import { useState, useEffect } from 'react';
2+
import { useState, useEffect, useRef } from 'react';
33
import { ChatHistory as History } from '@/types/chat';
44
import { useRouter } from 'next/navigation';
55
import Image from 'next/image';
66
import Spinner from '../Spinner';
77
import ModelModal from '../modals/ModelModal';
88
import EmbedModal from '../modals/EmbedModal';
99
import Modal from '../modals/Modal';
10-
import ChatMenu from './ChatMenu';
10+
import ChatMenu from './ChatHistoryEntry';
1111

1212
export default function ChatMenuNavbar() {
1313
const { user, signOut } = useAuth();
@@ -17,6 +17,7 @@ export default function ChatMenuNavbar() {
1717
const router = useRouter();
1818
const [chatHistory, setChatHistory] = useState<History>({ chats: [] });
1919
const [loadingHistory, setLoadingHistory] = useState(true);
20+
const menuRef = useRef<HTMLDivElement>(null);
2021

2122
// TODO: Fetch chat history from the server
2223
console.log(setChatHistory);
@@ -25,6 +26,23 @@ export default function ChatMenuNavbar() {
2526
setIsNavbarOpen(!isNavbarOpen);
2627
};
2728

29+
const handleClickOutside = (event: MouseEvent) => {
30+
if (
31+
window.innerWidth < 768 &&
32+
menuRef.current &&
33+
!menuRef.current.contains(event.target as Node)
34+
) {
35+
setIsNavbarOpen(false);
36+
}
37+
};
38+
39+
useEffect(() => {
40+
document.addEventListener('mousedown', handleClickOutside);
41+
return () => {
42+
document.removeEventListener('mousedown', handleClickOutside);
43+
};
44+
});
45+
2846
useEffect(() => {
2947
const fetchChatHistory = async () => {
3048
setLoadingHistory(false);
@@ -35,6 +53,7 @@ export default function ChatMenuNavbar() {
3553
return (
3654
<>
3755
<div
56+
ref={menuRef}
3857
className={`flex-shrink-0 overscroll-none bg-black transition-all duration-300 ${isNavbarOpen ? 'w-64' : 'w-0'}`}
3958
>
4059
<div className="flex h-full flex-col justify-between">
@@ -123,7 +142,7 @@ export default function ChatMenuNavbar() {
123142
<Spinner width="5" height="5" />
124143
</div>
125144
) : (
126-
<ChatMenu chats={chatHistory.chats} />
145+
chatHistory.chats.map((chat) => <ChatMenu key={chat.id} chat={chat} />)
127146
))}
128147

129148
{isNavbarOpen && (

src/app/help/page.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1+
'use client';
2+
3+
import { useAuth } from '@/contexts/AuthContext';
4+
import Spinner from '../components/Spinner';
5+
import Protected from '../components/Protected';
6+
17
export default function HelpPage() {
2-
// TODO: finish
8+
const { loading } = useAuth();
9+
10+
if (loading) {
11+
return (
12+
<div className="flex h-screen w-screen justify-center align-middle">
13+
<Spinner width="5" height="5" />
14+
</div>
15+
);
16+
}
317

418
return (
5-
<div>
19+
// TODO: Finish
20+
<Protected>
621
<h1>Help</h1>
722
<p>Here is some help text</p>
8-
</div>
23+
</Protected>
924
);
1025
}

src/app/not-found.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use client';
2+
3+
import { useState } from 'react';
4+
import { useRouter } from 'next/navigation';
5+
import { useAuth } from '@/contexts/AuthContext';
6+
import ChatMenuNavbar from '@/app/components/chat/ChatMenuNavbar';
7+
import ChatHeader from '@/app/components/chat/ChatHeader';
8+
import Spinner from './components/Spinner';
9+
import Protected from './components/Protected';
10+
11+
export default function NotFoundPage() {
12+
const { loading } = useAuth();
13+
const router = useRouter();
14+
const [timer, setTimer] = useState(5);
15+
16+
if (loading) {
17+
return (
18+
<div className="flex h-screen w-screen justify-center align-middle">
19+
<Spinner width="5" height="5" />
20+
</div>
21+
);
22+
}
23+
24+
setTimeout(() => {
25+
setTimer(timer - 1);
26+
if (timer === 0) {
27+
router.push('/');
28+
}
29+
}, 1000);
30+
31+
return (
32+
<Protected>
33+
<div className="flex h-svh flex-row gap-0">
34+
<ChatMenuNavbar />
35+
<div className="flex w-full flex-col">
36+
<ChatHeader />
37+
<div className="m-auto mt-10 flex w-4/5 flex-grow flex-col gap-3">
38+
<span className="text-7xl font-semibold">404 - Not Found</span>
39+
<span className="text-3xl font-semibold text-primaryColor">
40+
The requested page could not be found.
41+
</span>
42+
{timer > 0 ? (
43+
<span>Redirecting home in {timer} seconds.</span>
44+
) : (
45+
<span>Redirecting...</span>
46+
)}
47+
</div>
48+
</div>
49+
</div>
50+
</Protected>
51+
);
52+
}

src/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// TODO: Fix 'use client' directives - only put where needed
1+
// TODO: Fix 'use client' directives - only put where needed (needed at top of pages, not components)
22
'use client';
33

44
import { useAuth } from '@/contexts/AuthContext';

0 commit comments

Comments
 (0)