Skip to content

Commit

Permalink
Merge pull request #59 from dwhiffing/settings-modal
Browse files Browse the repository at this point in the history
Moved Settings to modal
  • Loading branch information
dwhiffing authored Sep 13, 2024
2 parents e6071d7 + 9c7a2dc commit f9eaf87
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 240 deletions.
11 changes: 7 additions & 4 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import MagicProvider from "@/components/MagicProvider";
import ChatProvider from "@/components/ChatProvider";
import { Toaster } from "@/components/ui/sonner";

import "./globals.css";
Expand All @@ -24,10 +25,12 @@ export default function RootLayout({
</head>
<body className={assistant.className}>
<MagicProvider>
<div className="flex h-screen w-full flex-col bg-background">
{children}
</div>
<Toaster position="top-right" />
<ChatProvider>
<div className="flex h-screen w-full flex-col bg-background">
{children}
</div>
<Toaster position="top-right" />
</ChatProvider>
</MagicProvider>
</body>
</html>
Expand Down
96 changes: 55 additions & 41 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import { useContracts } from "@/utils/useContracts";
import { ScrollArea } from "@/components/ui/scroll-area";
import { EditContractModal } from "@/components/EditContractModal";
import { ConfirmAlert } from "@/components/ConfirmAlert";
import { ChatSettingsModal } from "@/components/ChatSettingsModal";
import { shortenAddress } from "@/utils/shortenAddress";
import { toast } from "sonner";
import { useChat } from "@/components/ChatProvider";

export default function Page() {
const { contracts } = useContracts();
const [editContractKey, setEditContractKey] = useState<number | null>(null);
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
const {
magic,
teeWalletAddress,
isLoggedIn,
handleLogin,
handleLogout,
isLoading,
} = useMagic();
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
const { teeWalletAddress, isLoggedIn, handleLogin, handleLogout, isLoading } =
useMagic();
const { modelName } = useChat();

return (
<div className="flex flex-col h-screen">
Expand All @@ -34,45 +34,36 @@ export default function Page() {
) : isLoggedIn ? (
<>
<div className="flex flex-1 overflow-hidden">
{/* Comment to hide side nav */}
{process.env.NODE_ENV === "development" && (
<div className="hidden w-96 flex-col border-r bg-card p-4 sm:flex">
<div className="grid gap-2 p-2 text-foreground">
<div className="px-2 text-xs font-medium text-muted-foreground">
Uploaded Contracts
</div>

<ScrollArea className="max-h-[calc(100vh-11rem)]">
<div className="grid gap-2">
{contracts.map((contract) => (
<ContractItem
key={contract.key}
contract={contract}
onEdit={() => setEditContractKey(contract.key)}
/>
))}
</div>
</ScrollArea>
<Button onClick={() => setIsUploadModalOpen(true)}>
Upload Contract
</Button>
<div className="hidden w-72 md:w-96 flex-col border-r bg-card p-4 sm:flex">
<div className="grid gap-2 text-foreground">
<div className="px-2 text-xs font-medium text-muted-foreground">
Uploaded Contracts
</div>

<ScrollArea className="max-h-[calc(100vh-11rem)]">
<div className="grid gap-2">
{contracts.map((contract) => (
<ContractItem
key={contract.key}
contract={contract}
onEdit={() => setEditContractKey(contract.key)}
/>
))}
</div>
</ScrollArea>
<Button onClick={() => setIsUploadModalOpen(true)}>
Upload Contract
</Button>
</div>
)}
</div>

{/* Remove div with id=temp if enabling side nav */}
<div id="temp" className="flex-1 overflow-hidden flex flex-col">
{/* Top Navigation */}
<nav className="bg-background text-primary p-4 flex justify-between items-center">
<nav className="bg-background border-b text-primary p-4 flex justify-between items-center">
<h1 className="text-xl font-bold">Magic Chat Prototype</h1>
<div className="flex gap-4 items-center">
{teeWalletAddress && (
<p className="opacity-50 hidden md:block text-sm">
TEE Wallet: {teeWalletAddress}
</p>
)}
<Button onClick={() => magic?.wallet.showUI()}>
Show Wallet
<Button onClick={() => setIsSettingsModalOpen(true)}>
Settings
</Button>
<ConfirmAlert
onConfirm={handleLogout}
Expand All @@ -82,10 +73,33 @@ export default function Page() {
</div>
</nav>

<ChatWindow titleText="Magic Chat Prototype" />
<div className="flex-1">
<ChatWindow />
</div>

<div className="p-4 opacity-50 text-sm flex justify-between">
{teeWalletAddress && (
<p
className="cursor-pointer"
onClick={() => {
toast("Copied to clipboard");
navigator.clipboard.writeText(teeWalletAddress);
}}
>
Wallet Address: {shortenAddress(teeWalletAddress)}
</p>
)}

<p>Model: {modelName}</p>
</div>
</div>
</div>

<ChatSettingsModal
isOpen={isSettingsModalOpen}
onClose={() => setIsSettingsModalOpen(false)}
/>

<EditContractModal
contractKey={editContractKey}
onClose={() => setEditContractKey(null)}
Expand Down
69 changes: 69 additions & 0 deletions components/ChatProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client";

import { createContext, useContext, useState } from "react";
import { UseChatHelpers, UseChatOptions, useChat as useAiChat } from "ai/react";
import { MODELS } from "@/constants";
import { useContracts } from "@/utils/useContracts";
import { toast } from "sonner";

export const ChatContext = createContext<
Pick<
UseChatOptions & UseChatHelpers,
"messages" | "handleInputChange" | "handleSubmit" | "isLoading" | "input"
> & {
modelName: string;
clearOnChange: boolean;
onClearMessages: () => void;
setModelName: (name: string) => void;
setClearOnChange: (v: boolean) => void;
}
>({
messages: [],
handleInputChange: () => {},
handleSubmit: () => {},
isLoading: false,
input: "",
modelName: "",
clearOnChange: false,
onClearMessages: () => {},
setModelName: () => {},
setClearOnChange: () => {},
});

export const useChat = () => useContext(ChatContext);

const ChatProvider = ({ children }: any) => {
const { disabledKeys } = useContracts();
const [modelName, setModelName] = useState(MODELS["openai"][0]);
const [clearOnChange, setClearOnChange] = useState(false);

const chatContext = useAiChat({
api: "api/chat",
body: { disabledContractKeys: disabledKeys, modelName },
streamProtocol: "text",
onError: (e) => {
toast(e.message);
},
});

const onClearMessages = () => {
chatContext.setMessages([]);
};

return (
<ChatContext.Provider
value={{
...chatContext,
modelName,
setModelName,
clearOnChange,
setClearOnChange,
onClearMessages,
}}
>
{children}
</ChatContext.Provider>
);
};

export default ChatProvider;
90 changes: 0 additions & 90 deletions components/ChatSettings.tsx

This file was deleted.

Loading

0 comments on commit f9eaf87

Please sign in to comment.