Clean up deps
This commit is contained in:
parent
b38c49da59
commit
aa857aeb21
7 changed files with 2787 additions and 4425 deletions
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright 2023 Vercel, Inc.
|
Copyright 2024 Vercel, Inc.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { format, parseISO } from 'date-fns'
|
import { format, parseISO } from 'lib/utils'
|
||||||
|
|
||||||
interface Event {
|
interface Event {
|
||||||
date: string
|
date: string
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { CodeBlock } from '../ui/codeblock'
|
||||||
import { MemoizedReactMarkdown } from '../markdown'
|
import { MemoizedReactMarkdown } from '../markdown'
|
||||||
import remarkGfm from 'remark-gfm'
|
import remarkGfm from 'remark-gfm'
|
||||||
import remarkMath from 'remark-math'
|
import remarkMath from 'remark-math'
|
||||||
import { StreamableValue, useStreamableValue } from 'ai/rsc'
|
import { StreamableValue } from 'ai/rsc'
|
||||||
import { useStreamableText } from '@/lib/hooks/use-streamable-text'
|
import { useStreamableText } from '@/lib/hooks/use-streamable-text'
|
||||||
|
|
||||||
// Different types of message bubbles.
|
// Different types of message bubbles.
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useRef, useEffect, useId } from 'react'
|
import { useState, useRef, useEffect, useId } from 'react'
|
||||||
import { scaleLinear } from 'd3-scale'
|
import { subMonths, format } from 'lib/utils'
|
||||||
import { subMonths, format } from 'date-fns'
|
|
||||||
import { useResizeObserver } from 'usehooks-ts'
|
|
||||||
import { useAIState } from 'ai/rsc'
|
import { useAIState } from 'ai/rsc'
|
||||||
|
|
||||||
interface Stock {
|
interface Stock {
|
||||||
|
|
@ -12,6 +10,43 @@ interface Stock {
|
||||||
delta: number
|
delta: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scaleLinear(domain: [number, number], range: [number, number]) {
|
||||||
|
const [d0, d1] = domain
|
||||||
|
const [r0, r1] = range
|
||||||
|
|
||||||
|
return function scale(value: number): number {
|
||||||
|
return r0 + ((value - d0) / (d1 - d0)) * (r1 - r0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function useResizeObserver<T extends HTMLElement = HTMLElement>(
|
||||||
|
ref: React.RefObject<T>
|
||||||
|
) {
|
||||||
|
const [size, setSize] = useState({ width: 0, height: 0 })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.current) return
|
||||||
|
|
||||||
|
const observer = new ResizeObserver(([entry]) => {
|
||||||
|
if (entry.borderBoxSize && entry.borderBoxSize.length > 0) {
|
||||||
|
setSize({
|
||||||
|
width: entry.borderBoxSize[0].inlineSize,
|
||||||
|
height: entry.borderBoxSize[0].blockSize
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Fallback for browsers that don't support borderBoxSize
|
||||||
|
const { width, height } = entry.target.getBoundingClientRect()
|
||||||
|
setSize({ width, height })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.observe(ref.current)
|
||||||
|
return () => observer.disconnect()
|
||||||
|
}, [ref])
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
||||||
const [aiState, setAIState] = useAIState()
|
const [aiState, setAIState] = useAIState()
|
||||||
const id = useId()
|
const id = useId()
|
||||||
|
|
@ -26,15 +61,13 @@ export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
||||||
const [endHighlight, setEndHighlight] = useState(0)
|
const [endHighlight, setEndHighlight] = useState(0)
|
||||||
|
|
||||||
const chartRef = useRef<HTMLDivElement>(null)
|
const chartRef = useRef<HTMLDivElement>(null)
|
||||||
const { width = 0 } = useResizeObserver({
|
const { width = 0 } = useResizeObserver(chartRef)
|
||||||
ref: chartRef,
|
|
||||||
box: 'border-box'
|
|
||||||
})
|
|
||||||
|
|
||||||
const xToDate = scaleLinear(
|
const xToDate = scaleLinear(
|
||||||
[0, width],
|
[0, width],
|
||||||
[subMonths(new Date(), 6), new Date()]
|
[subMonths(new Date(), 6).getTime(), new Date().getTime()]
|
||||||
)
|
)
|
||||||
|
|
||||||
const xToValue = scaleLinear(
|
const xToValue = scaleLinear(
|
||||||
[0, width],
|
[0, width],
|
||||||
[price - price / 2, price + price / 2]
|
[price - price / 2, price + price / 2]
|
||||||
|
|
@ -46,9 +79,9 @@ export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
||||||
id,
|
id,
|
||||||
role: 'system' as const,
|
role: 'system' as const,
|
||||||
content: `[User has highlighted dates between between ${format(
|
content: `[User has highlighted dates between between ${format(
|
||||||
xToDate(startHighlight),
|
new Date(xToDate(startHighlight)),
|
||||||
'd LLL'
|
'd LLL'
|
||||||
)} and ${format(xToDate(endHighlight), 'd LLL, yyyy')}`
|
)} and ${format(new Date(xToDate(endHighlight)), 'd LLL, yyyy')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiState.messages[aiState.messages.length - 1]?.id === id) {
|
if (aiState.messages[aiState.messages.length - 1]?.id === id) {
|
||||||
|
|
@ -89,7 +122,7 @@ export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
||||||
setEndHighlight(0)
|
setEndHighlight(0)
|
||||||
|
|
||||||
setPriceAtTime({
|
setPriceAtTime({
|
||||||
time: format(xToDate(clientX), 'dd LLL yy'),
|
time: format(new Date(xToDate(clientX)), 'dd LLL yy'),
|
||||||
value: xToValue(clientX).toFixed(2),
|
value: xToValue(clientX).toFixed(2),
|
||||||
x: clientX - left
|
x: clientX - left
|
||||||
})
|
})
|
||||||
|
|
@ -109,7 +142,7 @@ export function Stock({ props: { symbol, price, delta } }: { props: Stock }) {
|
||||||
const { left } = chartRef.current.getBoundingClientRect()
|
const { left } = chartRef.current.getBoundingClientRect()
|
||||||
|
|
||||||
setPriceAtTime({
|
setPriceAtTime({
|
||||||
time: format(xToDate(clientX), 'dd LLL yy'),
|
time: format(new Date(xToDate(clientX)), 'dd LLL yy'),
|
||||||
value: xToValue(clientX).toFixed(2),
|
value: xToValue(clientX).toFixed(2),
|
||||||
x: clientX - left
|
x: clientX - left
|
||||||
})
|
})
|
||||||
|
|
|
||||||
45
lib/utils.ts
45
lib/utils.ts
|
|
@ -87,3 +87,48 @@ export const getMessageFromCode = (resultCode: string) => {
|
||||||
return 'Logged in!'
|
return 'Logged in!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function format(date: Date, formatString: string) {
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = date.getMonth()
|
||||||
|
const day = date.getDate()
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0')
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||||
|
|
||||||
|
const monthNames = [
|
||||||
|
'Jan',
|
||||||
|
'Feb',
|
||||||
|
'Mar',
|
||||||
|
'Apr',
|
||||||
|
'May',
|
||||||
|
'Jun',
|
||||||
|
'Jul',
|
||||||
|
'Aug',
|
||||||
|
'Sep',
|
||||||
|
'Oct',
|
||||||
|
'Nov',
|
||||||
|
'Dec'
|
||||||
|
]
|
||||||
|
|
||||||
|
return formatString
|
||||||
|
.replace('yyyy', year.toString())
|
||||||
|
.replace('yy', String(year).slice(-2))
|
||||||
|
.replace('LLL', monthNames[month])
|
||||||
|
.replace('MM', String(month + 1).padStart(2, '0'))
|
||||||
|
.replace('dd', String(day).padStart(2, '0'))
|
||||||
|
.replace('d', day.toString())
|
||||||
|
.replace('HH', hours)
|
||||||
|
.replace('mm', minutes)
|
||||||
|
.replace('ss', seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseISO(dateString: string) {
|
||||||
|
return new Date(dateString)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function subMonths(date: Date, amount: number) {
|
||||||
|
const newDate: Date = new Date(date)
|
||||||
|
newDate.setMonth(newDate.getMonth() - amount)
|
||||||
|
return newDate
|
||||||
|
}
|
||||||
|
|
|
||||||
46
package.json
46
package.json
|
|
@ -4,16 +4,12 @@
|
||||||
"dev": "next dev --turbo",
|
"dev": "next dev --turbo",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
|
||||||
"lint:fix": "next lint --fix",
|
|
||||||
"preview": "next build && next start",
|
|
||||||
"seed": "node -r dotenv/config ./scripts/seed.mjs",
|
|
||||||
"type-check": "tsc --noEmit",
|
"type-check": "tsc --noEmit",
|
||||||
"format:write": "prettier --write \"{app,lib,components}/**/*.{ts,tsx,mdx}\" --cache",
|
"format:write": "prettier --write \"{app,lib,components}/**/*.{ts,tsx,mdx}\" --cache",
|
||||||
"format:check": "prettier --check \"{app,lib,components}**/*.{ts,tsx,mdx}\" --cache"
|
"format:check": "prettier --check \"{app,lib,components}**/*.{ts,tsx,mdx}\" --cache"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/openai": "^0.0.34",
|
"@ai-sdk/openai": "^0.0.53",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
"@radix-ui/react-alert-dialog": "^1.1.1",
|
||||||
"@radix-ui/react-dialog": "^1.1.1",
|
"@radix-ui/react-dialog": "^1.1.1",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
|
|
@ -26,20 +22,16 @@
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
"@radix-ui/react-tooltip": "^1.1.2",
|
||||||
"@vercel/analytics": "^1.3.1",
|
"@vercel/analytics": "^1.3.1",
|
||||||
"@vercel/kv": "^2.0.0",
|
"@vercel/kv": "^2.0.0",
|
||||||
"@vercel/og": "^0.6.2",
|
"ai": "^3.3.17",
|
||||||
"ai": "^3.2.16",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"d3-scale": "^4.0.2",
|
"framer-motion": "^11.3.30",
|
||||||
"date-fns": "^3.6.0",
|
"geist": "^1.3.1",
|
||||||
"focus-trap-react": "^10.2.3",
|
|
||||||
"framer-motion": "^11.2.12",
|
|
||||||
"geist": "^1.3.0",
|
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"next": "14.2.4",
|
"next": "14.2.6",
|
||||||
"next-auth": "5.0.0-beta.4",
|
"next-auth": "5.0.0-beta.4",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"openai": "^4.52.2",
|
"openai": "^4.56.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-intersection-observer": "^9.10.3",
|
"react-intersection-observer": "^9.10.3",
|
||||||
|
|
@ -49,29 +41,21 @@
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
"sonner": "^1.5.0",
|
"sonner": "^1.5.0",
|
||||||
"usehooks-ts": "^3.1.0",
|
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.14",
|
||||||
"@types/d3-scale": "^4.0.8",
|
"@types/node": "^22.5.0",
|
||||||
"@types/node": "^20.14.9",
|
"@types/react": "^18.3.4",
|
||||||
"@types/react": "^18.3.3",
|
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/react-syntax-highlighter": "^15.5.13",
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
"@typescript-eslint/parser": "^7.14.1",
|
"autoprefixer": "^10.4.20",
|
||||||
"autoprefixer": "^10.4.19",
|
"postcss": "^8.4.41",
|
||||||
"dotenv": "^16.4.5",
|
"prettier": "^3.3.3",
|
||||||
"eslint": "^8.56.0",
|
"tailwind-merge": "^2.5.2",
|
||||||
"eslint-config-next": "14.1.0",
|
"tailwindcss": "^3.4.10",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
|
||||||
"eslint-plugin-tailwindcss": "^3.14.0",
|
|
||||||
"postcss": "^8.4.39",
|
|
||||||
"prettier": "^3.3.2",
|
|
||||||
"tailwind-merge": "^2.3.0",
|
|
||||||
"tailwindcss": "^3.4.4",
|
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript": "^5.5.2"
|
"typescript": "^5.5.4"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.6.3"
|
"packageManager": "pnpm@8.6.3"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7058
pnpm-lock.yaml
generated
7058
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue