Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
toandev95 committed Oct 23, 2024
1 parent e4e5b76 commit dacc5bd
Show file tree
Hide file tree
Showing 50 changed files with 1,568 additions and 1,421 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
# Get your Groq API Key here: https://console.groq.com/keys
GROQ_API_KEY=XXXXXXXX
OPENAI_API_KEY=XXXXXXXX
18 changes: 16 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,24 @@
"prettier",
"plugin:tailwindcss/recommended"
],
"plugins": ["tailwindcss"],
"plugins": [
"@typescript-eslint/eslint-plugin",
"tailwindcss",
"simple-import-sort",
"unused-imports"
],
"rules": {
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"tailwindcss/no-custom-classname": "off",
"tailwindcss/classnames-order": "off"
"tailwindcss/classnames-order": "off",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
},
"settings": {
"tailwindcss": {
Expand Down
7 changes: 3 additions & 4 deletions app/(chat)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { nanoid } from '@/lib/utils'
import { getMissingKeys } from '@/app/actions'
import { Chat } from '@/components/chat'
import { AI } from '@/lib/chat/actions'
import { Session } from '@/lib/types'
import { getMissingKeys } from '@/app/actions'
import { nanoid } from '@/lib/utils'

export const metadata = {
title: 'StockBot powered by Groq'
title: 'StockBot powered by ToanChat'
}

export default async function IndexPage() {
Expand Down
2 changes: 1 addition & 1 deletion app/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function refreshHistory(path: string) {
}

export async function getMissingKeys() {
const keysRequired: string[] = ['GROQ_API_KEY']
const keysRequired: string[] = ['OPENAI_API_KEY']
return keysRequired
.map(key => (process.env[key] ? '' : key))
.filter(key => key !== '')
Expand Down
4 changes: 2 additions & 2 deletions app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface ErrorProps {
reset: () => void
}

export default function Error({ error, reset }: ErrorProps) {
export default function Error({ error }: ErrorProps) {
useEffect(() => {
console.error(error)
}, [error])
Expand All @@ -17,7 +17,7 @@ export default function Error({ error, reset }: ErrorProps) {
<div className="text-red-700 font-medium">Error: {error.message}</div>
<div className="flex items-center mt-2">
<a
href="https://github.com/bklieger-groq/stockbot-on-groq/issues"
href="https://github.com/toandev95/stockbot-on-groq/issues"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center text-sm text-red-800 hover:text-red-900"
Expand Down
38 changes: 19 additions & 19 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,76 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;

--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;

--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;

--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;

--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;

--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;

--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;

--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;

--radius: 0.5rem;
}

.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;

--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;

--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;

--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;

--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;

--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;

--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;

--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
}
13 changes: 7 additions & 6 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { GeistSans } from 'geist/font/sans'
import '@/app/globals.css'

import { GeistMono } from 'geist/font/mono'
import { GeistSans } from 'geist/font/sans'

import '@/app/globals.css'
import { cn } from '@/lib/utils'
import { Header } from '@/components/header'
// import { ThemeToggle } from '@/components/theme-toggle'
import { Providers } from '@/components/providers'
import { Header } from '@/components/header'
import { Toaster } from '@/components/ui/sonner'
import { cn } from '@/lib/utils'

export const metadata = {
metadataBase: process.env.VERCEL_URL
? new URL(`https://${process.env.VERCEL_URL}`)
: undefined,
title: {
default: 'StockBot powered by Groq',
template: `%s - StockBot powered by Groq`
default: 'StockBot powered by ToanChat',
template: `%s - StockBot powered by ToanChat`
},
description:
'Lightning Fast AI Chatbot that Responds With Live Interactive Stock Charts, Financials, News, Screeners, and More.',
Expand Down
2 changes: 1 addition & 1 deletion components/button-scroll-to-bottom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import * as React from 'react'

import { cn } from '@/lib/utils'
import { Button, type ButtonProps } from '@/components/ui/button'
import { IconArrowDown } from '@/components/ui/icons'
import { cn } from '@/lib/utils'

interface ButtonScrollToBottomProps extends ButtonProps {
isAtBottom: boolean
Expand Down
4 changes: 1 addition & 3 deletions components/chat-list.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Separator } from '@/components/ui/separator'
import { UIState } from '@/lib/chat/actions'
import { Session } from '@/lib/types'
import Link from 'next/link'
import { ExclamationTriangleIcon } from '@radix-ui/react-icons'

export interface ChatList {
messages: UIState
session?: Session
isShared: boolean
}

export function ChatList({ messages, session, isShared }: ChatList) {
export function ChatList({ messages }: ChatList) {
if (!messages.length) {
return null
}
Expand Down
81 changes: 39 additions & 42 deletions components/chat-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useActions, useUIState } from 'ai/rsc'
import { nanoid } from 'nanoid'
import * as React from 'react'
import { useState, useEffect } from 'react'
import { Button } from '@/components/ui/button'
import { PromptForm } from '@/components/prompt-form'
import { useEffect, useState } from 'react'

import { ButtonScrollToBottom } from '@/components/button-scroll-to-bottom'
import { IconShare } from '@/components/ui/icons'
import { FooterText } from '@/components/footer'
import { useAIState, useActions, useUIState } from 'ai/rsc'
import { PromptForm } from '@/components/prompt-form'
import type { AI } from '@/lib/chat/actions'
import { nanoid } from 'nanoid'

import { UserMessage } from './stocks/message'

export interface ChatPanelProps {
Expand All @@ -20,50 +20,14 @@ export interface ChatPanelProps {
}

export function ChatPanel({
id,
title,
input,
setInput,
isAtBottom,
scrollToBottom
}: ChatPanelProps) {
const [aiState] = useAIState()
const [messages, setMessages] = useUIState<typeof AI>()
const { submitUserMessage } = useActions()

const exampleMessages = [
{
heading: 'What is the price',
subheading: 'of Apple Inc.?',
message: 'What is the price of Apple stock?'
},
{
heading: 'Show me a stock chart',
subheading: 'for $GOOGL',
message: 'Show me a stock chart for $GOOGL'
},
{
heading: 'What are some recent',
subheading: `events about Amazon?`,
message: `What are some recent events about Amazon?`
},
{
heading: `What are Microsoft's`,
subheading: 'latest financials?',
message: `What are Microsoft's latest financials?`
},
{
heading: 'How is the stock market',
subheading: 'performing today by sector?',
message: `How is the stock market performing today by sector?`
},
{
heading: 'Show me a screener',
subheading: 'to find new stocks',
message: 'Show me a screener to find new stocks'
}
]

interface ExampleMessage {
heading: string
subheading: string
Expand All @@ -73,6 +37,39 @@ export function ChatPanel({
const [randExamples, setRandExamples] = useState<ExampleMessage[]>([])

useEffect(() => {
const exampleMessages = [
{
heading: 'Giá cổ phiếu',
subheading: 'của Apple Inc.?',
message: 'Giá cổ phiếu của Apple Inc. là bao nhiêu?'
},
{
heading: 'Cho tôi xem biểu đồ cổ phiếu',
subheading: 'của $GOOGL',
message: 'Cho tôi xem biểu đồ cổ phiếu của $GOOGL'
},
{
heading: 'Các sự kiện gần đây',
subheading: `về Amazon?`,
message: `Các sự kiện gần đây về Amazon là gì?`
},
{
heading: `Thông tin tài chính mới nhất`,
subheading: 'của Microsoft?',
message: `Thông tin tài chính mới nhất của Microsoft là gì?`
},
{
heading: 'Thị trường chứng khoán',
subheading: 'hiện đang thế nào?',
message: `Thị trường chứng khoán hiện đang thế nào theo từng ngành?`
},
{
heading: 'Cho tôi xem một bộ lọc',
subheading: 'để tìm cổ phiếu mới',
message: 'Cho tôi xem một bộ lọc để tìm cổ phiếu mới'
}
]

const shuffledExamples = [...exampleMessages].sort(
() => 0.5 - Math.random()
)
Expand Down
19 changes: 10 additions & 9 deletions components/chat.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
'use client'

import { cn } from '@/lib/utils'
import { useAIState, useUIState } from 'ai/rsc'
import { usePathname, useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
import { toast } from 'sonner'

import { ChatList } from '@/components/chat-list'
import { ChatPanel } from '@/components/chat-panel'
import { EmptyScreen } from '@/components/empty-screen'
import { MissingApiKeyBanner } from '@/components/missing-api-key-banner'
import { TickerTape } from '@/components/tradingview/ticker-tape'
import { useLocalStorage } from '@/lib/hooks/use-local-storage'
import { useEffect, useState } from 'react'
import { useUIState, useAIState } from 'ai/rsc'
import { Message, Session } from '@/lib/types'
import { usePathname, useRouter } from 'next/navigation'
import { useScrollAnchor } from '@/lib/hooks/use-scroll-anchor'
import { toast } from 'sonner'
import { TickerTape } from '@/components/tradingview/ticker-tape'
import { MissingApiKeyBanner } from '@/components/missing-api-key-banner'
import { Message, Session } from '@/lib/types'
import { cn } from '@/lib/utils'

export interface ChatProps extends React.ComponentProps<'div'> {
initialMessages?: Message[]
Expand All @@ -28,7 +29,7 @@ export function Chat({ id, className, session, missingKeys }: ChatProps) {
const [messages] = useUIState()
const [aiState] = useAIState()

const [_, setNewChatId] = useLocalStorage('newChatId', id)
const [, setNewChatId] = useLocalStorage('newChatId', id)

useEffect(() => {
if (session?.user) {
Expand Down
Loading

0 comments on commit dacc5bd

Please sign in to comment.