Skip to content

Commit 7c855ce

Browse files
authored
Workspace route (#1360)
* initial work * switcher works * adjust middleware * fix new chat * fix azure models * adjust workspace page * fix setup route
1 parent b9370cc commit 7c855ce

File tree

18 files changed

+295
-208
lines changed

18 files changed

+295
-208
lines changed
File renamed without changes.
File renamed without changes.
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
"use client"
2+
3+
import { Dashboard } from "@/components/ui/dashboard"
4+
import { ChatbotUIContext } from "@/context/context"
5+
import { getAssistantWorkspacesByWorkspaceId } from "@/db/assistants"
6+
import { getChatsByWorkspaceId } from "@/db/chats"
7+
import { getCollectionWorkspacesByWorkspaceId } from "@/db/collections"
8+
import { getFileWorkspacesByWorkspaceId } from "@/db/files"
9+
import { getFoldersByWorkspaceId } from "@/db/folders"
10+
import { getModelWorkspacesByWorkspaceId } from "@/db/models"
11+
import { getPresetWorkspacesByWorkspaceId } from "@/db/presets"
12+
import { getPromptWorkspacesByWorkspaceId } from "@/db/prompts"
13+
import { getAssistantImageFromStorage } from "@/db/storage/assistant-images"
14+
import { getToolWorkspacesByWorkspaceId } from "@/db/tools"
15+
import { getWorkspaceById } from "@/db/workspaces"
16+
import { convertBlobToBase64 } from "@/lib/blob-to-b64"
17+
import { supabase } from "@/lib/supabase/browser-client"
18+
import { LLMID } from "@/types"
19+
import { useParams, useRouter } from "next/navigation"
20+
import { ReactNode, useContext, useEffect, useState } from "react"
21+
import Loading from "../loading"
22+
23+
interface WorkspaceLayoutProps {
24+
children: ReactNode
25+
}
26+
27+
export default function WorkspaceLayout({ children }: WorkspaceLayoutProps) {
28+
const router = useRouter()
29+
30+
const params = useParams()
31+
const workspaceId = params.workspaceid as string
32+
33+
const {
34+
setChatSettings,
35+
setAssistants,
36+
setAssistantImages,
37+
setChats,
38+
setCollections,
39+
setFolders,
40+
setFiles,
41+
setPresets,
42+
setPrompts,
43+
setTools,
44+
setModels,
45+
selectedWorkspace,
46+
setSelectedWorkspace,
47+
setSelectedChat,
48+
setChatMessages,
49+
setUserInput,
50+
setIsGenerating,
51+
setFirstTokenReceived,
52+
setChatFiles,
53+
setChatImages,
54+
setNewMessageFiles,
55+
setNewMessageImages,
56+
setShowFilesDisplay
57+
} = useContext(ChatbotUIContext)
58+
59+
const [loading, setLoading] = useState(true)
60+
61+
useEffect(() => {
62+
;(async () => {
63+
const session = (await supabase.auth.getSession()).data.session
64+
65+
if (!session) {
66+
return router.push("/login")
67+
} else {
68+
await fetchWorkspaceData(workspaceId)
69+
}
70+
})()
71+
}, [])
72+
73+
useEffect(() => {
74+
const isInChat = window?.location?.pathname === "/chat"
75+
76+
if (!selectedWorkspace && !isInChat) {
77+
setLoading(false)
78+
return
79+
}
80+
81+
;(async () => await fetchWorkspaceData(workspaceId))()
82+
83+
setUserInput("")
84+
setChatMessages([])
85+
setSelectedChat(null)
86+
87+
setIsGenerating(false)
88+
setFirstTokenReceived(false)
89+
90+
setChatFiles([])
91+
setChatImages([])
92+
setNewMessageFiles([])
93+
setNewMessageImages([])
94+
setShowFilesDisplay(false)
95+
}, [workspaceId])
96+
97+
const fetchWorkspaceData = async (workspaceId: string) => {
98+
setLoading(true)
99+
100+
const workspace = await getWorkspaceById(workspaceId)
101+
setSelectedWorkspace(workspace)
102+
103+
const assistantData = await getAssistantWorkspacesByWorkspaceId(workspaceId)
104+
setAssistants(assistantData.assistants)
105+
106+
for (const assistant of assistantData.assistants) {
107+
let url = ""
108+
109+
if (assistant.image_path) {
110+
url = (await getAssistantImageFromStorage(assistant.image_path)) || ""
111+
}
112+
113+
if (url) {
114+
const response = await fetch(url)
115+
const blob = await response.blob()
116+
const base64 = await convertBlobToBase64(blob)
117+
118+
setAssistantImages(prev => [
119+
...prev,
120+
{
121+
assistantId: assistant.id,
122+
path: assistant.image_path,
123+
base64,
124+
url
125+
}
126+
])
127+
} else {
128+
setAssistantImages(prev => [
129+
...prev,
130+
{
131+
assistantId: assistant.id,
132+
path: assistant.image_path,
133+
base64: "",
134+
url
135+
}
136+
])
137+
}
138+
}
139+
140+
const chats = await getChatsByWorkspaceId(workspaceId)
141+
setChats(chats)
142+
143+
const collectionData =
144+
await getCollectionWorkspacesByWorkspaceId(workspaceId)
145+
setCollections(collectionData.collections)
146+
147+
const folders = await getFoldersByWorkspaceId(workspaceId)
148+
setFolders(folders)
149+
150+
const fileData = await getFileWorkspacesByWorkspaceId(workspaceId)
151+
setFiles(fileData.files)
152+
153+
const presetData = await getPresetWorkspacesByWorkspaceId(workspaceId)
154+
setPresets(presetData.presets)
155+
156+
const promptData = await getPromptWorkspacesByWorkspaceId(workspaceId)
157+
setPrompts(promptData.prompts)
158+
159+
const toolData = await getToolWorkspacesByWorkspaceId(workspaceId)
160+
setTools(toolData.tools)
161+
162+
const modelData = await getModelWorkspacesByWorkspaceId(workspaceId)
163+
setModels(modelData.models)
164+
165+
setChatSettings({
166+
model: (workspace?.default_model || "gpt-4-1106-preview") as LLMID,
167+
prompt:
168+
workspace?.default_prompt ||
169+
"You are a friendly, helpful AI assistant.",
170+
temperature: workspace?.default_temperature || 0.5,
171+
contextLength: workspace?.default_context_length || 4096,
172+
includeProfileContext: workspace?.include_profile_context || true,
173+
includeWorkspaceInstructions:
174+
workspace?.include_workspace_instructions || true,
175+
embeddingsProvider:
176+
(workspace?.embeddings_provider as "openai" | "local") || "openai"
177+
})
178+
179+
setLoading(false)
180+
}
181+
182+
if (loading) {
183+
return <Loading />
184+
}
185+
186+
return <Dashboard>{children}</Dashboard>
187+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use client"
2+
3+
import { ChatbotUIContext } from "@/context/context"
4+
import { useContext } from "react"
5+
6+
export default function WorkspacePage() {
7+
const { selectedWorkspace } = useContext(ChatbotUIContext)
8+
9+
return (
10+
<div className="flex h-screen w-full flex-col items-center justify-center">
11+
<div className="text-4xl">{selectedWorkspace?.name}</div>
12+
</div>
13+
)
14+
}

app/[locale]/chat/layout.tsx

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

app/[locale]/login/page.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { Label } from "@/components/ui/label"
55
import { createClient } from "@/lib/supabase/server"
66
import { Database } from "@/supabase/types"
77
import { createServerClient } from "@supabase/ssr"
8+
import { get } from "@vercel/edge-config"
89
import { Metadata } from "next"
910
import { cookies, headers } from "next/headers"
1011
import { redirect } from "next/navigation"
11-
import { get } from "@vercel/edge-config"
1212

1313
export const metadata: Metadata = {
1414
title: "Login"
@@ -34,7 +34,18 @@ export default async function Login({
3434
const session = (await supabase.auth.getSession()).data.session
3535

3636
if (session) {
37-
return redirect("/chat")
37+
const { data: homeWorkspace, error } = await supabase
38+
.from("workspaces")
39+
.select("*")
40+
.eq("user_id", session.user.id)
41+
.eq("is_home", true)
42+
.single()
43+
44+
if (!homeWorkspace) {
45+
throw new Error(error.message)
46+
}
47+
48+
return redirect(`/${homeWorkspace.id}/chat`)
3849
}
3950

4051
const signIn = async (formData: FormData) => {
@@ -54,7 +65,20 @@ export default async function Login({
5465
return redirect(`/login?message=${error.message}`)
5566
}
5667

57-
return redirect("/chat")
68+
const { data: homeWorkspace, error: homeWorkspaceError } = await supabase
69+
.from("workspaces")
70+
.select("*")
71+
.eq("user_id", data.user.id)
72+
.eq("is_home", true)
73+
.single()
74+
75+
if (!homeWorkspace) {
76+
throw new Error(
77+
homeWorkspaceError?.message || "An unexpected error occurred"
78+
)
79+
}
80+
81+
return redirect(`/${homeWorkspace.id}/chat`)
5882
}
5983

6084
const signUp = async (formData: FormData) => {

app/[locale]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default function HomePage() {
1818

1919
<Link
2020
className="mt-4 flex w-[200px] items-center justify-center rounded-md bg-blue-500 p-2 font-semibold"
21-
href="/chat"
21+
href="/login"
2222
>
2323
Start Chatting
2424
<IconArrowRight className="ml-1" size={20} />

app/[locale]/setup/page.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import { ChatbotUIContext } from "@/context/context"
44
import { getProfileByUserId, updateProfile } from "@/db/profile"
5-
import { getWorkspacesByUserId } from "@/db/workspaces"
5+
import {
6+
getHomeWorkspaceByUserId,
7+
getWorkspacesByUserId
8+
} from "@/db/workspaces"
69
import {
710
fetchHostedModels,
811
fetchOpenRouterModels
@@ -86,7 +89,10 @@ export default function SetupPage() {
8689
setAvailableOpenRouterModels(openRouterModels)
8790
}
8891

89-
return router.push("/chat")
92+
const homeWorkspaceId = await getHomeWorkspaceByUserId(
93+
session.user.id
94+
)
95+
return router.push(`/${homeWorkspaceId}/chat`)
9096
}
9197
}
9298
})()
@@ -144,7 +150,7 @@ export default function SetupPage() {
144150
setSelectedWorkspace(homeWorkspace!)
145151
setWorkspaces(workspaces)
146152

147-
router.refresh()
153+
return router.push(`/${homeWorkspace?.id}/chat`)
148154
}
149155

150156
const renderStep = (stepNum: number) => {

components/chat/chat-hooks/use-chat-handler.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ export const useChatHandler = () => {
7373
}
7474
}, [isPromptPickerOpen, isAtPickerOpen, isToolPickerOpen])
7575

76-
const handleNewChat = () => {
76+
const handleNewChat = async () => {
77+
if (!selectedWorkspace) return
78+
7779
setUserInput("")
7880
setChatMessages([])
7981
setSelectedChat(null)
@@ -138,7 +140,7 @@ export const useChatHandler = () => {
138140
})
139141
}
140142

141-
return router.push("/chat")
143+
return router.push(`/${selectedWorkspace.id}/chat`)
142144
}
143145

144146
const handleFocusChatInput = () => {

components/sidebar/items/all/sidebar-display-item.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const SidebarItem: FC<SidebarItemProps> = ({
6060
setChats(prevState => [createdChat, ...prevState])
6161
setSelectedAssistant(assistant)
6262

63-
return router.push(`/chat/${createdChat.id}`)
63+
return router.push(`/${selectedWorkspace.id}/chat/${createdChat.id}`)
6464
},
6565
tools: async (item: any) => {},
6666
models: async (item: any) => {}

0 commit comments

Comments
 (0)