Skip to content
38 linesCodeBlameRaw
1import { Tabs, useGlobalSearchParams } from "expo-router";
2import { Blocks, CircleUser, Code2, MessagesSquare } from "lucide-react-native";
3import { useEffect } from "react";
4
5import { useSignedIn } from "@/lib/session";
6import { useColors } from "@/theme";
7
8/**
9 * The signed-in app: Chat, Code, Customize and You, as the site's phone
10 * layout has its bottom bar (apps/web/app/components/mobile.tsx). Home,
11 * Notifications, Agents and Artifacts join as they get screens.
12 */
13export default function AppLayout() {
14 const colors = useColors();
15 const { workspace, selectWorkspace } = useSignedIn();
16 // A link names its workspace (`/chat?workspace=acme`, lib/links.ts): switch to it.
17 const { workspace: linked } = useGlobalSearchParams<{ workspace?: string }>();
18 useEffect(() => {
19 if (linked && linked.toLowerCase() !== workspace?.slug.toLowerCase()) void selectWorkspace(linked);
20 }, [linked, workspace?.slug, selectWorkspace]);
21
22 return (
23 <Tabs
24 screenOptions={{
25 headerShown: false,
26 tabBarActiveTintColor: colors.accent,
27 tabBarInactiveTintColor: colors.muted,
28 tabBarStyle: { backgroundColor: colors.surface, borderTopColor: colors.line },
29 }}
30 >
31 <Tabs.Screen name="index" options={{ href: null }} />
32 <Tabs.Screen name="chat" options={{ title: "Chat", tabBarIcon: ({ color, size }) => <MessagesSquare color={color} size={size} /> }} />
33 <Tabs.Screen name="code" options={{ title: "Code", tabBarIcon: ({ color, size }) => <Code2 color={color} size={size} /> }} />
34 <Tabs.Screen name="customize" options={{ title: "Customize", tabBarIcon: ({ color, size }) => <Blocks color={color} size={size} /> }} />
35 <Tabs.Screen name="you" options={{ title: "You", tabBarIcon: ({ color, size }) => <CircleUser color={color} size={size} /> }} />
36 </Tabs>
37 );
38}