mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-07-24 15:27:00 +08:00
feat: add chat logo
This commit is contained in:
1
.env.dev
Normal file
1
.env.dev
Normal file
@ -0,0 +1 @@
|
||||
OPENAI_API_KEY=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
|
@ -1 +0,0 @@
|
||||
OPENAI_API_KEY=<YOUR_API_KEY>
|
@ -1,7 +1,6 @@
|
||||
import { useEffect } from "react";
|
||||
import { useChatStore } from "@/store";
|
||||
import Icon from "../Icon";
|
||||
import GitHubStarBadge from "../GitHubStarBadge";
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
@ -14,7 +13,7 @@ const Header = (props: Props) => {
|
||||
const title = currentChat?.title || "SQL Chat";
|
||||
|
||||
useEffect(() => {
|
||||
document.title = `${title} - SQL Chat`;
|
||||
document.title = `${title}`;
|
||||
}, [title]);
|
||||
|
||||
return (
|
||||
@ -28,7 +27,13 @@ const Header = (props: Props) => {
|
||||
<Icon.IoIosMenu className="text-gray-600 w-full h-auto" />
|
||||
</label>
|
||||
<span className="w-auto text-left block lg:hidden">{title}</span>
|
||||
<GitHubStarBadge className="hidden lg:flex ml-2" />
|
||||
<a
|
||||
className="ml-1 w-10 h-10 p-1 rounded-lg hidden lg:flex flex-row justify-center items-center hover:bg-gray-100"
|
||||
href="https://github.com/bytebase/sqlchat"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon.IoLogoGithub className="text-gray-600 w-6 h-auto" />
|
||||
</a>
|
||||
</div>
|
||||
<span className="w-auto text-center h-8 p-1 hidden lg:block">{title}</span>
|
||||
<div className="mr-2 sm:mr-3 relative flex flex-row justify-end items-center">
|
||||
@ -37,7 +42,7 @@ const Header = (props: Props) => {
|
||||
className="flex flex-row justify-center items-center h-10 px-3 py-1 rounded-md whitespace-nowrap hover:bg-gray-100"
|
||||
target="_blank"
|
||||
>
|
||||
<img className="h-5 sm:h-6 w-auto" src="/craft-by-bytebase.webp" alt="" />
|
||||
<img className="h-6 w-auto ml-1" src="/craft-by-bytebase.webp" alt="" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,7 +47,7 @@ const MessageView = (props: Props) => {
|
||||
>
|
||||
{isCurrentUser ? (
|
||||
<>
|
||||
<div className="mt-0.5 w-auto max-w-full bg-indigo-600 text-white px-4 py-2 rounded-lg whitespace-pre-wrap">
|
||||
<div className="w-auto max-w-full bg-indigo-600 text-white px-4 py-2 rounded-lg whitespace-pre-wrap">
|
||||
{message.content}
|
||||
</div>
|
||||
<div className="w-10 h-10 p-1 border rounded-full flex justify-center items-center ml-2 shrink-0">
|
||||
@ -56,11 +56,11 @@ const MessageView = (props: Props) => {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="w-10 h-10 p-1 border rounded-full flex justify-center items-center mr-2 shrink-0">
|
||||
<Icon.AiOutlineRobot className="w-6 h-6" />
|
||||
<div className="w-10 h-10 p-1 flex justify-center items-center mr-2 shrink-0">
|
||||
<img src="/chat-logo-bot.webp" alt="" />
|
||||
</div>
|
||||
<ReactMarkdown
|
||||
className="mt-0.5 w-auto max-w-[calc(100%-4rem)] bg-gray-100 px-4 py-2 rounded-lg prose prose-neutral"
|
||||
className="w-auto max-w-[calc(100%-4rem)] bg-gray-100 px-4 py-2 rounded-lg prose prose-neutral"
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
pre({ node, className, children, ...props }) {
|
||||
|
@ -140,7 +140,7 @@ const ConnectionSidebar = () => {
|
||||
className={`w-full h-14 rounded-l-lg p-2 mt-1 group ${currentConnectionCtx === undefined && "bg-gray-100 shadow"}`}
|
||||
onClick={() => connectionStore.setCurrentConnectionCtx(undefined)}
|
||||
>
|
||||
<Icon.AiOutlineRobot className="w-7 h-auto mx-auto" />
|
||||
<img src="/chat-logo-bot.webp" className="w-7 h-auto mx-auto" alt="" />
|
||||
</button>
|
||||
{connectionList.map((connection) => (
|
||||
<button
|
||||
@ -180,62 +180,65 @@ const ConnectionSidebar = () => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`w-64 h-full overflow-y-auto bg-gray-100 px-4 pt-2 ${databaseList.length === 0 && "!pt-4"}`}>
|
||||
{databaseList.length > 0 && (
|
||||
<div className="w-full sticky top-0 bg-gray-100 z-1 mb-4">
|
||||
<p className="text-sm leading-6 mb-1 text-gray-500">Select your database:</p>
|
||||
<select
|
||||
className="w-full select select-bordered"
|
||||
value={currentConnectionCtx?.database?.name}
|
||||
onChange={(e) => handleDatabaseNameSelect(e.target.value)}
|
||||
<div className="p-4 w-64 h-full overflow-y-auto bg-gray-100">
|
||||
<img className="px-4" src="/chat-logo.webp" alt="" />
|
||||
<div className={`${databaseList.length > 0 && "pt-2"}`}>
|
||||
{databaseList.length > 0 && (
|
||||
<div className="w-full sticky top-0 bg-gray-100 z-1 mb-4">
|
||||
<p className="text-sm leading-6 mb-1 text-gray-500">Select your database:</p>
|
||||
<select
|
||||
className="w-full select select-bordered"
|
||||
value={currentConnectionCtx?.database?.name}
|
||||
onChange={(e) => handleDatabaseNameSelect(e.target.value)}
|
||||
>
|
||||
{databaseList.map((database) => (
|
||||
<option key={database.name} value={database.name}>
|
||||
{database.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
{chatList.map((chat) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
className={`w-full mt-2 first:mt-4 py-3 pl-4 pr-2 rounded-lg flex flex-row justify-start items-center cursor-pointer border border-transparent group hover:bg-gray-50 ${
|
||||
chat.id === chatStore.currentChat?.id && "!bg-white border-gray-200 font-medium"
|
||||
}`}
|
||||
onClick={() => handleChatSelect(chat)}
|
||||
>
|
||||
{databaseList.map((database) => (
|
||||
<option key={database.name} value={database.name}>
|
||||
{database.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
{chatList.map((chat) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
className={`w-full mt-2 first:mt-4 py-3 pl-4 pr-2 rounded-lg flex flex-row justify-start items-center cursor-pointer border border-transparent group hover:bg-gray-50 ${
|
||||
chat.id === chatStore.currentChat?.id && "!bg-white border-gray-200 font-medium"
|
||||
}`}
|
||||
onClick={() => handleChatSelect(chat)}
|
||||
{chat.id === chatStore.currentChat?.id ? (
|
||||
<Icon.IoChatbubble className="w-5 h-auto mr-1.5 shrink-0" />
|
||||
) : (
|
||||
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-1.5 opacity-80 shrink-0" />
|
||||
)}
|
||||
<span className="truncate grow">{chat.title || "SQL Chat"}</span>
|
||||
<span className="ml-0.5 shrink-0 hidden group-hover:flex flex-row justify-end items-center space-x-1">
|
||||
<Icon.FiEdit3
|
||||
className="w-4 h-auto opacity-60 hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleEditChatTitle(chat);
|
||||
}}
|
||||
/>
|
||||
<Icon.IoClose
|
||||
className="w-5 h-auto opacity-60 hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteChat(chat);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
<button
|
||||
className="w-full my-4 py-3 px-4 border rounded-lg flex flex-row justify-center items-center text-gray-500 hover:text-gray-700 hover:bg-gray-50"
|
||||
onClick={handleCreateChat}
|
||||
>
|
||||
{chat.id === chatStore.currentChat?.id ? (
|
||||
<Icon.IoChatbubble className="w-5 h-auto mr-1.5 shrink-0" />
|
||||
) : (
|
||||
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-1.5 opacity-80 shrink-0" />
|
||||
)}
|
||||
<span className="truncate grow">{chat.title || "SQL Chat"}</span>
|
||||
<span className="ml-0.5 shrink-0 hidden group-hover:flex flex-row justify-end items-center space-x-1">
|
||||
<Icon.FiEdit3
|
||||
className="w-4 h-auto opacity-60 hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleEditChatTitle(chat);
|
||||
}}
|
||||
/>
|
||||
<Icon.IoClose
|
||||
className="w-5 h-auto opacity-60 hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteChat(chat);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
<button
|
||||
className="w-full my-4 py-3 px-4 border rounded-lg flex flex-row justify-center items-center text-gray-500 hover:text-gray-700 hover:bg-gray-50"
|
||||
onClick={handleCreateChat}
|
||||
>
|
||||
<Icon.AiOutlinePlus className="w-5 h-auto mr-1" />
|
||||
New Chat
|
||||
</button>
|
||||
<Icon.AiOutlinePlus className="w-5 h-auto mr-1" />
|
||||
New Chat
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
@ -43,7 +43,9 @@ const EmptyView = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div className={`${className || ""} w-full h-full flex flex-col justify-start items-center`}>
|
||||
<p className=" text-5xl font-medium leading-loose mb-8">SQL Chat</p>
|
||||
<p className="w-96 font-medium leading-loose mb-8">
|
||||
<img src="/chat-logo-and-text.webp" alt="" />
|
||||
</p>
|
||||
<div className="w-full grid grid-cols-2 sm:grid-cols-3 gap-4">
|
||||
<div className="w-full flex flex-col justify-start items-center">
|
||||
<Icon.BsSun className="w-8 h-auto opacity-80" />
|
||||
|
@ -4,8 +4,8 @@ import Icon from "./Icon";
|
||||
const MessageLoader = () => {
|
||||
return (
|
||||
<div className={`w-full max-w-full flex flex-row justify-start items-start my-4 pr-8 sm:pr-24`}>
|
||||
<div className="w-10 h-10 p-1 border rounded-full flex justify-center items-center mr-2 shrink-0">
|
||||
<Icon.AiOutlineRobot className="w-6 h-6" />
|
||||
<div className="w-10 h-10 p-1 flex justify-center items-center mr-2 shrink-0">
|
||||
<img src="/chat-logo-bot.webp" alt="" />
|
||||
</div>
|
||||
<div className="mt-0.5 w-12 bg-gray-100 px-4 py-2 rounded-lg">
|
||||
<ThreeDots wrapperClass="opacity-80" width="24" height="24" color="" />
|
||||
|
BIN
public/chat-logo-and-text.webp
Normal file
BIN
public/chat-logo-and-text.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
BIN
public/chat-logo-bot.webp
Normal file
BIN
public/chat-logo-bot.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
BIN
public/chat-logo.webp
Normal file
BIN
public/chat-logo.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -1 +1 @@
|
||||
export const openAIApiKey = process.env.OPENAI_API_KEY;
|
||||
export const openAIApiKey = "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";
|
||||
|
Reference in New Issue
Block a user