From 30c2742650a198ea68a26fbe0cf69f9928f92c3e Mon Sep 17 00:00:00 2001 From: sadmann7 Date: Fri, 26 Apr 2024 08:23:16 +0600 Subject: [PATCH] feat: remove icon.tsx --- .env.example | 4 - .../ai/_components/chat-message.tsx | 47 --------- .../ai/_components/chat-panel.tsx | 75 --------------- .../ai/_components/chat-scroll-anchor.tsx | 29 ------ .../(experimental)/ai/_components/chat.tsx | 55 ----------- .../ai/_components/code-block.tsx | 89 ------------------ .../ai/_components/empty-chat-screen.tsx | 34 ------- .../ai/_components/markdown.tsx | 9 -- .../ai/_components/prompt-form.tsx | 88 ----------------- .../_components/scroll-to-bottom-button.tsx | 35 ------- src/app/(experimental)/ai/page.tsx | 9 -- src/app/(experimental)/layout.tsx | 15 --- src/app/icon.png | Bin 0 -> 479 bytes src/app/icon.tsx | 35 ------- src/env.js | 2 - 15 files changed, 526 deletions(-) delete mode 100644 src/app/(experimental)/ai/_components/chat-message.tsx delete mode 100644 src/app/(experimental)/ai/_components/chat-panel.tsx delete mode 100644 src/app/(experimental)/ai/_components/chat-scroll-anchor.tsx delete mode 100644 src/app/(experimental)/ai/_components/chat.tsx delete mode 100644 src/app/(experimental)/ai/_components/code-block.tsx delete mode 100644 src/app/(experimental)/ai/_components/empty-chat-screen.tsx delete mode 100644 src/app/(experimental)/ai/_components/markdown.tsx delete mode 100644 src/app/(experimental)/ai/_components/prompt-form.tsx delete mode 100644 src/app/(experimental)/ai/_components/scroll-to-bottom-button.tsx delete mode 100644 src/app/(experimental)/ai/page.tsx delete mode 100644 src/app/(experimental)/layout.tsx create mode 100644 src/app/icon.png delete mode 100644 src/app/icon.tsx diff --git a/.env.example b/.env.example index 04dc1787e..3db95ec13 100644 --- a/.env.example +++ b/.env.example @@ -47,7 +47,3 @@ STRIPE_WEBHOOK_SECRET="whsec_" # found at https://dashboard.stripe.com/test/products STRIPE_STD_MONTHLY_PRICE_ID="price_" STRIPE_PRO_MONTHLY_PRICE_ID="price_" - -# Optional -# OpenAI API Key -OPENAI_API_KEY="sk-" diff --git a/src/app/(experimental)/ai/_components/chat-message.tsx b/src/app/(experimental)/ai/_components/chat-message.tsx deleted file mode 100644 index 36093dded..000000000 --- a/src/app/(experimental)/ai/_components/chat-message.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { AvatarIcon } from "@radix-ui/react-icons" -import { type Message } from "ai" -import remarkGfm from "remark-gfm" -import remarkMath from "remark-math" - -import { cn } from "@/lib/utils" -import { Icons } from "@/components/icons" - -import { MemoizedReactMarkdown } from "./markdown" - -export interface ChatMessageProps { - message: Message -} - -export function ChatMessage({ message }: ChatMessageProps) { - return ( -
-
- {message.role === "user" ? ( -
-
- {children}

- }, - }} - > - {message.content} -
-
-
- ) -} diff --git a/src/app/(experimental)/ai/_components/chat-panel.tsx b/src/app/(experimental)/ai/_components/chat-panel.tsx deleted file mode 100644 index d35a95ccd..000000000 --- a/src/app/(experimental)/ai/_components/chat-panel.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { ReloadIcon, StopIcon } from "@radix-ui/react-icons" -import { type UseChatHelpers } from "ai/react" - -import { Button } from "@/components/ui/button" - -import { PromptForm } from "./prompt-form" -import { ScrollToBottomButton } from "./scroll-to-bottom-button" - -export interface ChatPanelProps - extends Pick< - UseChatHelpers, - | "append" - | "isLoading" - | "reload" - | "messages" - | "stop" - | "input" - | "setInput" - > { - id?: string -} - -export function ChatPanel({ - id, - isLoading, - stop, - append, - reload, - input, - setInput, - messages, -}: ChatPanelProps) { - return ( -
- -
-
- {isLoading ? ( - - ) : ( - messages?.length > 0 && ( - - ) - )} -
- { - await append({ - id, - content: value, - role: "user", - }) - }} - input={input} - setInput={setInput} - isLoading={isLoading} - /> -
-
- ) -} diff --git a/src/app/(experimental)/ai/_components/chat-scroll-anchor.tsx b/src/app/(experimental)/ai/_components/chat-scroll-anchor.tsx deleted file mode 100644 index d3437cede..000000000 --- a/src/app/(experimental)/ai/_components/chat-scroll-anchor.tsx +++ /dev/null @@ -1,29 +0,0 @@ -"use client" - -import * as React from "react" -import { useInView } from "react-intersection-observer" - -import { useAtBottom } from "@/hooks/use-at-bottom" - -interface ChatScrollAnchorProps { - trackVisibility?: boolean -} - -export function ChatScrollAnchor({ trackVisibility }: ChatScrollAnchorProps) { - const isAtBottom = useAtBottom() - const { ref, entry, inView } = useInView({ - trackVisibility, - delay: 100, - rootMargin: "0px 0px -150px 0px", - }) - - React.useEffect(() => { - if (isAtBottom && trackVisibility && !inView) { - entry?.target.scrollIntoView({ - block: "start", - }) - } - }, [inView, entry, isAtBottom, trackVisibility]) - - return
-} diff --git a/src/app/(experimental)/ai/_components/chat.tsx b/src/app/(experimental)/ai/_components/chat.tsx deleted file mode 100644 index 0dfbd6862..000000000 --- a/src/app/(experimental)/ai/_components/chat.tsx +++ /dev/null @@ -1,55 +0,0 @@ -"use client" - -// Original source: https://github.com/vercel-labs/ai-chatbot/blob/main/lib/hooks/use-at-bottom.tsx -import { useChat } from "ai/react" -import { toast } from "sonner" - -import { Separator } from "@/components/ui/separator" - -import { ChatMessage } from "./chat-message" -import { ChatPanel } from "./chat-panel" -import { ChatScrollAnchor } from "./chat-scroll-anchor" -import { EmptyChatScreen } from "./empty-chat-screen" - -export function Chat() { - const { messages, append, reload, stop, isLoading, input, setInput } = - useChat({ - onResponse: (response) => { - console.log(response) - }, - onError: (error) => { - toast.error(error.message) - }, - }) - - return ( - <> -
- {messages.length ? ( - <> - {messages.map((message, i) => ( -
- - {i < messages.length - 1 ? ( - - ) : null} -
- ))} - - - ) : ( - - )} -
- - - ) -} diff --git a/src/app/(experimental)/ai/_components/code-block.tsx b/src/app/(experimental)/ai/_components/code-block.tsx deleted file mode 100644 index 4de7dff87..000000000 --- a/src/app/(experimental)/ai/_components/code-block.tsx +++ /dev/null @@ -1,89 +0,0 @@ -// Original source: https://github.com/vercel-labs/ai-chatbot/blob/main/components/ui/codeblock.tsx - -"use client" - -import * as React from "react" -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" -import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism" - -interface Props { - language: string - value: string -} - -interface languageMap { - [key: string]: string | undefined -} - -export const programmingLanguages: languageMap = { - javascript: ".js", - python: ".py", - java: ".java", - c: ".c", - cpp: ".cpp", - "c++": ".cpp", - "c#": ".cs", - ruby: ".rb", - php: ".php", - swift: ".swift", - "objective-c": ".m", - kotlin: ".kt", - typescript: ".ts", - go: ".go", - perl: ".pl", - rust: ".rs", - scala: ".scala", - haskell: ".hs", - lua: ".lua", - shell: ".sh", - sql: ".sql", - html: ".html", - css: ".css", - // add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component -} - -export const generateRandomString = (length: number, lowercase = false) => { - const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789" // excluding similar looking characters like Z, 2, I, 1, O, 0 - let result = "" - for (let i = 0; i < length; i++) { - result += chars.charAt(Math.floor(Math.random() * chars.length)) - } - return lowercase ? result.toLowerCase() : result -} - -const CodeBlock: React.FC = React.memo(({ language, value }) => { - return ( -
-
- {language} -
- - {value} - -
- ) -}) -CodeBlock.displayName = "CodeBlock" - -export { CodeBlock } diff --git a/src/app/(experimental)/ai/_components/empty-chat-screen.tsx b/src/app/(experimental)/ai/_components/empty-chat-screen.tsx deleted file mode 100644 index b009a3046..000000000 --- a/src/app/(experimental)/ai/_components/empty-chat-screen.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { type UseChatHelpers } from "ai/react" - -import { Button } from "@/components/ui/button" -import { Card } from "@/components/ui/card" -import { Shell } from "@/components/shell" - -const examples = [ - "Get me the top 5 stories on Hacker News in markdown table format. Use columns like title, link, score, and comments.", - "Summarize the comments in the top hacker news story.", - "What is the top story on Hacker News right now?", -] - -type EmptyChatScreenProps = Pick - -export function EmptyChatScreen({ setInput }: EmptyChatScreenProps) { - return ( - - - {examples.map((example, i) => ( - - ))} - - - ) -} diff --git a/src/app/(experimental)/ai/_components/markdown.tsx b/src/app/(experimental)/ai/_components/markdown.tsx deleted file mode 100644 index a6edc2f19..000000000 --- a/src/app/(experimental)/ai/_components/markdown.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from "react" -import ReactMarkdown, { type Options } from "react-markdown" - -export const MemoizedReactMarkdown: React.FC = React.memo( - ReactMarkdown, - (prevProps, nextProps) => - prevProps.children === nextProps.children && - prevProps.className === nextProps.className -) diff --git a/src/app/(experimental)/ai/_components/prompt-form.tsx b/src/app/(experimental)/ai/_components/prompt-form.tsx deleted file mode 100644 index 542a4c22b..000000000 --- a/src/app/(experimental)/ai/_components/prompt-form.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import * as React from "react" -import { PaperPlaneIcon } from "@radix-ui/react-icons" -import { type UseChatHelpers } from "ai/react" - -import { showErrorToast } from "@/lib/handle-error" -import { useEnterSubmit } from "@/hooks/use-enter-submit" -import { Button } from "@/components/ui/button" -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/components/ui/tooltip" -import { Icons } from "@/components/icons" -import { TextareaAutosize } from "@/components/textarea-autosize" - -export interface PromptFormProps - extends Pick { - onSubmit: (value: string) => Promise - isLoading: boolean -} - -export function PromptForm({ - onSubmit, - input, - setInput, - isLoading, -}: PromptFormProps) { - const { formRef, onKeyDown } = useEnterSubmit() - const inputRef = React.useRef(null) - - React.useEffect(() => { - if (!inputRef.current) return - inputRef.current.focus() - }, []) - - async function onFormSubmit(e: React.FormEvent) { - try { - e.preventDefault() - if (!input?.trim()) return - setInput("") - await onSubmit(input) - } catch (err) { - showErrorToast(err) - } - } - - return ( -
void onFormSubmit(e)} - ref={formRef} - > - setInput(e.target.value)} - placeholder="Send a message" - spellCheck={false} - className="resize-none" - /> -
- - - - - Send message - -
- - ) -} diff --git a/src/app/(experimental)/ai/_components/scroll-to-bottom-button.tsx b/src/app/(experimental)/ai/_components/scroll-to-bottom-button.tsx deleted file mode 100644 index 836871e10..000000000 --- a/src/app/(experimental)/ai/_components/scroll-to-bottom-button.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" - -import { ArrowDownIcon } from "@radix-ui/react-icons" - -import { cn } from "@/lib/utils" -import { useAtBottom } from "@/hooks/use-at-bottom" -import { Button, type ButtonProps } from "@/components/ui/button" - -export function ScrollToBottomButton({ className, ...props }: ButtonProps) { - const isAtBottom = useAtBottom() - - function scrollToBottom(behavior: ScrollBehavior = "auto") { - window.scrollTo({ - top: document.body.offsetHeight, - behavior: behavior, - }) - } - - return ( - - ) -} diff --git a/src/app/(experimental)/ai/page.tsx b/src/app/(experimental)/ai/page.tsx deleted file mode 100644 index 9791cc0e8..000000000 --- a/src/app/(experimental)/ai/page.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Chat } from "./_components/chat" - -export default function AIPage() { - return ( -
- -
- ) -} diff --git a/src/app/(experimental)/layout.tsx b/src/app/(experimental)/layout.tsx deleted file mode 100644 index d5d69096a..000000000 --- a/src/app/(experimental)/layout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { getCachedUser } from "@/lib/queries/user" -import { SiteHeader } from "@/components/layouts/site-header" - -export default async function ExperimentalLayout({ - children, -}: React.PropsWithChildren) { - const user = await getCachedUser() - - return ( -
- -
{children}
-
- ) -} diff --git a/src/app/icon.png b/src/app/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..de496353a1c61eef15fb436bacc4368bfdb3e3e5 GIT binary patch literal 479 zcmV<50U-W~P)INM_C%F6nfN;nOFH$%T`oW{A zmgehwFG&I5i}7c)04rYPC zv@e%SoX=-?$}~l`!0~uYU)mIAfs(aX58Ur}3`%B9$YsN3;jzk}dE=B5KCKiB%R6 znGr2f30e7A;3pEPSPEriwOS!i%1R>wLM2(R*Xiqfy&iwD(U^c5^m4gy#FrL&tqncd zh=9tl-|y4OsQ$2G7VzADwf>djSDbTca%DkFvgD>^rC^u@B0F3sUgWjrDOfXvr - S -
- ), - // ImageResponse options - { - // For convenience, we can re-use the exported icons size metadata - // config to also set the ImageResponse's width and height. - ...size, - } - ) -} diff --git a/src/env.js b/src/env.js index 6969396e3..2f29d50c0 100644 --- a/src/env.js +++ b/src/env.js @@ -20,7 +20,6 @@ export const env = createEnv({ STRIPE_WEBHOOK_SECRET: z.string().min(1), STRIPE_STD_MONTHLY_PRICE_ID: z.string().min(1), STRIPE_PRO_MONTHLY_PRICE_ID: z.string().min(1), - OPENAI_API_KEY: z.string().optional(), }, /** @@ -59,7 +58,6 @@ export const env = createEnv({ STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET, STRIPE_STD_MONTHLY_PRICE_ID: process.env.STRIPE_STD_MONTHLY_PRICE_ID, STRIPE_PRO_MONTHLY_PRICE_ID: process.env.STRIPE_PRO_MONTHLY_PRICE_ID, - OPENAI_API_KEY: process.env.OPENAI_API_KEY, }, /** * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially