Update examples and improve stability (#271)

This commit is contained in:
Jeremy 2024-03-19 01:35:03 +03:00 committed by GitHub
parent 25e4128e25
commit 70ed5c4f47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 118 additions and 101 deletions

View file

@ -7,13 +7,13 @@ const placeholderEvents = [
}
]
export const EventsSkeleton = ({ events = placeholderEvents }) => {
export const EventsSkeleton = () => {
return (
<div className="-mt-2 flex flex-col gap-2 py-4">
<div className="-mt-2 flex w-full flex-col gap-2 py-4">
{placeholderEvents.map(event => (
<div
key={event.date}
className="max-w-96 flex gap-1 shrink-0 flex-col rounded-lg bg-zinc-800 p-4"
className="flex shrink-0 flex-col gap-1 rounded-lg bg-zinc-800 p-4"
>
<div className="w-fit rounded-md bg-zinc-700 text-sm text-transparent">
{event.date}

View file

@ -8,11 +8,11 @@ interface Event {
export function Events({ props: events }: { props: Event[] }) {
return (
<div className="-mt-2 flex flex-col gap-2">
<div className="-mt-2 flex w-full flex-col gap-2 py-4">
{events.map(event => (
<div
key={event.date}
className="max-w-96 flex shrink-0 flex-col rounded-lg bg-zinc-800 p-4 gap-1"
className="flex shrink-0 flex-col gap-1 rounded-lg bg-zinc-800 p-4"
>
<div className="text-sm text-zinc-400">
{format(parseISO(event.date), 'dd LLL, yyyy')}

View file

@ -18,9 +18,7 @@ const Purchase = dynamic(
{
ssr: false,
loading: () => (
<div className="rounded-lg bg-zinc-900 px-4 py-5 text-center text-xs">
Loading stock info...
</div>
<div className="h-[375px] rounded-xl border bg-zinc-950 p-4 text-green-400 sm:h-[314px]" />
)
}
)
@ -30,7 +28,7 @@ const Stocks = dynamic(() => import('./stocks').then(mod => mod.Stocks), {
loading: () => <StocksSkeleton />
})
const Events = dynamic(() => import('./event').then(mod => mod.Events), {
const Events = dynamic(() => import('./events').then(mod => mod.Events), {
ssr: false,
loading: () => <EventsSkeleton />
})

View file

@ -7,18 +7,18 @@ import { formatNumber } from '@/lib/utils'
import type { AI } from '@/lib/chat/actions'
interface Purchase {
defaultAmount?: number
name: string
numberOfShares?: number
symbol: string
price: number
status: 'requires_action' | 'completed' | 'expired'
}
export function Purchase({
props: { defaultAmount, name, price, status = 'expired' }
props: { numberOfShares, symbol, price, status = 'requires_action' }
}: {
props: Purchase
}) {
const [value, setValue] = useState(defaultAmount || 100)
const [value, setValue] = useState(numberOfShares || 100)
const [purchasingUI, setPurchasingUI] = useState<null | React.ReactNode>(null)
const [aiState, setAIState] = useAIState<typeof AI>()
const [, setMessages] = useUIState<typeof AI>()
@ -60,11 +60,11 @@ export function Purchase({
}
return (
<div className="rounded-xl border bg-zinc-950 p-4 text-green-400 mt-2">
<div className="rounded-xl border bg-zinc-950 p-4 text-green-400">
<div className="float-right inline-block rounded-full bg-white/10 px-2 py-1 text-xs">
+1.23%
</div>
<div className="text-lg text-zinc-300">{name}</div>
<div className="text-lg text-zinc-300">{symbol}</div>
<div className="text-3xl font-bold">${price}</div>
{purchasingUI ? (
<div className="mt-4 text-zinc-200">{purchasingUI}</div>
@ -100,14 +100,14 @@ export function Purchase({
<div className="flex flex-wrap items-center text-xl font-bold sm:items-end sm:gap-2 sm:text-3xl">
<div className="flex basis-1/3 flex-col tabular-nums sm:basis-auto sm:flex-row sm:items-center sm:gap-2">
{value}
<span className="mb-1 text-sm font-normal text-zinc-600 dark:text-zinc-400 sm:mb-0">
<span className="mb-1 text-sm font-normal text-zinc-600 sm:mb-0 dark:text-zinc-400">
shares
</span>
</div>
<div className="basis-1/3 text-center sm:basis-auto">×</div>
<span className="flex basis-1/3 flex-col tabular-nums sm:basis-auto sm:flex-row sm:items-center sm:gap-2">
${price}
<span className="mb-1 ml-1 text-sm font-normal text-zinc-600 dark:text-zinc-400 sm:mb-0">
<span className="mb-1 ml-1 text-sm font-normal text-zinc-600 sm:mb-0 dark:text-zinc-400">
per share
</span>
</span>
@ -118,9 +118,9 @@ export function Purchase({
</div>
<button
className="mt-6 w-full rounded-lg bg-green-500 px-4 py-2 text-zinc-900 dark:bg-green-500"
className="mt-6 w-full rounded-lg bg-green-500 px-4 py-2 font-bold text-zinc-900 hover:bg-green-600"
onClick={async () => {
const response = await confirmPurchase(name, price, value)
const response = await confirmPurchase(symbol, price, value)
setPurchasingUI(response.purchasingUI)
// Insert a new system message to the UI.
@ -135,7 +135,7 @@ export function Purchase({
</>
) : status === 'completed' ? (
<p className="mb-2 text-white">
You have successfully purchased {value} ${name}. Total cost:{' '}
You have successfully purchased {value} ${symbol}. Total cost:{' '}
{formatNumber(value * price)}
</p>
) : status === 'expired' ? (

View file

@ -1,9 +1,9 @@
export const StocksSkeleton = () => {
return (
<div className="mb-4 flex flex-col gap-2 overflow-y-scroll pb-4 text-sm sm:flex-row">
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-900 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-900 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-900 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
</div>
)
}

View file

@ -15,45 +15,53 @@ export function Stocks({ props: stocks }: { props: Stock[] }) {
const { submitUserMessage } = useActions()
return (
<div className="mb-4 flex flex-col gap-2 overflow-y-scroll pb-4 text-sm sm:flex-row">
{stocks.map(stock => (
<button
key={stock.symbol}
className="flex cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-700 sm:w-52"
onClick={async () => {
const response = await submitUserMessage(`View ${stock.symbol}`)
setMessages(currentMessages => [...currentMessages, response])
}}
>
<div
className={`text-xl ${
stock.delta > 0 ? 'text-green-600' : 'text-red-600'
} flex w-11 flex-row justify-center rounded-md bg-white/10 p-2`}
<div>
<div className="mb-4 flex flex-col gap-2 overflow-y-scroll pb-4 text-sm sm:flex-row">
{stocks.map(stock => (
<button
key={stock.symbol}
className="flex cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-700 sm:w-52"
onClick={async () => {
const response = await submitUserMessage(`View ${stock.symbol}`)
setMessages(currentMessages => [...currentMessages, response])
}}
>
{stock.delta > 0 ? '↑' : '↓'}
</div>
<div className="flex flex-col">
<div className="bold uppercase text-zinc-300">{stock.symbol}</div>
<div className="text-base text-zinc-500">${stock.price}</div>
</div>
<div className="ml-auto flex flex-col">
<div
className={`${
className={`text-xl ${
stock.delta > 0 ? 'text-green-600' : 'text-red-600'
} bold text-right uppercase`}
} flex w-11 flex-row justify-center rounded-md bg-white/10 p-2`}
>
{` ${((stock.delta / stock.price) * 100).toFixed(2)}%`}
{stock.delta > 0 ? '↑' : '↓'}
</div>
<div
className={`${
stock.delta > 0 ? 'text-green-700' : 'text-red-700'
} text-right text-base`}
>
{stock.delta}
<div className="flex flex-col">
<div className="bold uppercase text-zinc-300">{stock.symbol}</div>
<div className="text-base text-zinc-500">
${stock.price.toExponential(1)}
</div>
</div>
</div>
</button>
))}
<div className="ml-auto flex flex-col">
<div
className={`${
stock.delta > 0 ? 'text-green-600' : 'text-red-600'
} bold text-right uppercase`}
>
{` ${((stock.delta / stock.price) * 100).toExponential(1)}%`}
</div>
<div
className={`${
stock.delta > 0 ? 'text-green-700' : 'text-red-700'
} text-right text-base`}
>
{stock.delta.toExponential(1)}
</div>
</div>
</button>
))}
</div>
<div className="p-4 text-center text-sm text-zinc-500">
Note: Data and latency are simulated for illustrative purposes and
should not be considered as financial advice.
</div>
</div>
)
}