Skip to content

Commit b4a5e4c

Browse files
committed
chore: apply branding
1 parent d4caa05 commit b4a5e4c

26 files changed

+4082
-3312
lines changed

app/(chat)/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Session } from '@/lib/types'
66
import { getMissingKeys } from '@/app/actions'
77

88
export const metadata = {
9-
title: 'Next.js AI Chatbot'
9+
title: 'New Chat'
1010
}
1111

1212
export default async function IndexPage() {

app/layout.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ export const metadata = {
1313
? new URL(`https://${process.env.VERCEL_URL}`)
1414
: undefined,
1515
title: {
16-
default: 'Next.js AI Chatbot',
17-
template: `%s - Next.js AI Chatbot`
16+
default: 'OpenRouter Tool Calling Demo',
17+
template: `%s - OpenRouter Tool Calling Demo`
1818
},
19-
description: 'An AI-powered chatbot template built with Next.js and Vercel.',
19+
description:
20+
'An AI-powered chatbot template built with OpenRouter, Next.js and Vercel AI SDK.',
2021
icons: {
2122
icon: '/favicon.ico',
2223
shortcut: '/favicon-16x16.png',

app/opengraph-image.jpg

104 KB
Loading

app/opengraph-image.png

-424 KB
Binary file not shown.

app/twitter-image.jpg

126 KB
Loading

app/twitter-image.png

-424 KB
Binary file not shown.

components/chat-message.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import remarkMath from 'remark-math'
88
import { cn } from '@/lib/utils'
99
import { CodeBlock } from '@/components/ui/codeblock'
1010
import { MemoizedReactMarkdown } from '@/components/markdown'
11-
import { IconOpenAI, IconUser } from '@/components/ui/icons'
11+
import { IconOpenRouter, IconUser } from '@/components/ui/icons'
1212
import { ChatMessageActions } from '@/components/chat-message-actions'
1313

1414
export interface ChatMessageProps {
@@ -29,7 +29,7 @@ export function ChatMessage({ message, ...props }: ChatMessageProps) {
2929
: 'bg-primary text-primary-foreground'
3030
)}
3131
>
32-
{message.role === 'user' ? <IconUser /> : <IconOpenAI />}
32+
{message.role === 'user' ? <IconUser /> : <IconOpenRouter />}
3333
</div>
3434
<div className="flex-1 px-1 ml-4 space-y-2 overflow-hidden">
3535
<MemoizedReactMarkdown

components/chat-panel.tsx

+8-8
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,23 @@ export function ChatPanel({
3737
const exampleMessages = [
3838
{
3939
heading: 'What are the',
40-
subheading: 'trending memecoins today?',
41-
message: `What are the trending memecoins today?`
40+
subheading: 'trending meme stocks today?',
41+
message: `What are the trending meme stocks today?`
4242
},
4343
{
4444
heading: 'What is the price of',
45-
subheading: '$DOGE right now?',
46-
message: 'What is the price of $DOGE right now?'
45+
subheading: '$NVDA right now?',
46+
message: 'What is the price of $NVDA right now?'
4747
},
4848
{
4949
heading: 'I would like to buy',
50-
subheading: '42 $DOGE',
51-
message: `I would like to buy 42 $DOGE`
50+
subheading: '42 $NVDA',
51+
message: `I would like to buy 42 $NVDA`
5252
},
5353
{
5454
heading: 'What are some',
55-
subheading: `recent events about $DOGE?`,
56-
message: `What are some recent events about $DOGE?`
55+
subheading: `recent events about $NVDA?`,
56+
message: `What are some recent events about $NVDA?`
5757
}
5858
]
5959

components/clear-history.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function ClearHistory({
4242
</AlertDialogTrigger>
4343
<AlertDialogContent>
4444
<AlertDialogHeader>
45-
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
45+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
4646
<AlertDialogDescription>
4747
This will permanently delete your chat history and remove your data
4848
from our servers.

components/empty-screen.tsx

+2-18
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import { UseChatHelpers } from 'ai/react'
2-
3-
import { Button } from '@/components/ui/button'
41
import { ExternalLink } from '@/components/external-link'
5-
import { IconArrowRight } from '@/components/ui/icons'
62

73
export function EmptyScreen() {
84
return (
95
<div className="mx-auto max-w-2xl px-4">
106
<div className="flex flex-col gap-2 rounded-lg border bg-background p-8">
117
<h1 className="text-lg font-semibold">
12-
Welcome to Next.js AI Chatbot!
8+
Welcome to OpenRouter + Next.js Demo!
139
</h1>
1410
<p className="leading-normal text-muted-foreground">
1511
This is an open source AI chatbot app template built with{' '}
@@ -18,19 +14,7 @@ export function EmptyScreen() {
1814
Vercel AI SDK
1915
</ExternalLink>
2016
, and{' '}
21-
<ExternalLink href="https://vercel.com/storage/kv">
22-
Vercel KV
23-
</ExternalLink>
24-
.
25-
</p>
26-
<p className="leading-normal text-muted-foreground">
27-
It uses{' '}
28-
<ExternalLink href="https://vercel.com/blog/ai-sdk-3-generative-ui">
29-
React Server Components
30-
</ExternalLink>{' '}
31-
to combine text with generative UI as output of the LLM. The UI state
32-
is synced through the SDK so the model is aware of your interactions
33-
as they happen.
17+
<ExternalLink href="https://openrouter.ai">OpenRouter</ExternalLink>.
3418
</p>
3519
</div>
3620
</div>

components/footer.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ export function FooterText({ className, ...props }: React.ComponentProps<'p'>) {
1212
)}
1313
{...props}
1414
>
15-
Open source AI chatbot built with{' '}
16-
<ExternalLink href="https://nextjs.org">Next.js</ExternalLink> and{' '}
15+
Open source AI tool calling chatbot built with{' '}
16+
<ExternalLink href="https://nextjs.org">Next.js</ExternalLink>,{' '}
17+
<ExternalLink href="https://openrouter.ai">OpenRouter</ExternalLink>, and{' '}
1718
<ExternalLink href="https://github.com/vercel/ai">
1819
Vercel AI SDK
1920
</ExternalLink>

components/header.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { auth } from '@/auth'
66
import { Button, buttonVariants } from '@/components/ui/button'
77
import {
88
IconGitHub,
9-
IconNextChat,
9+
IconOpenRouter,
1010
IconSeparator,
1111
IconVercel
1212
} from '@/components/ui/icons'
@@ -28,9 +28,9 @@ async function UserOrLogin() {
2828
<SidebarToggle />
2929
</>
3030
) : (
31-
<Link href="/new" rel="nofollow">
32-
<IconNextChat className="size-6 mr-2 dark:hidden" inverted />
33-
<IconNextChat className="hidden size-6 mr-2 dark:block" />
31+
<Link href="/new" rel="nofollow" className="flex items-center mr-2">
32+
<IconOpenRouter className="size-3.5 mr-2 inline" />
33+
<span className="font-medium text-sm">OpenRouter</span>
3434
</Link>
3535
)}
3636
<div className="flex items-center">

components/sidebar-actions.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export function SidebarActions({
8181
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
8282
<AlertDialogContent>
8383
<AlertDialogHeader>
84-
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
84+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
8585
<AlertDialogDescription>
8686
This will permanently delete your chat message and remove your
8787
data from our servers.

components/stocks/events-skeleton.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const EventsSkeleton = () => {
1313
{placeholderEvents.map(event => (
1414
<div
1515
key={event.date}
16-
className="flex shrink-0 flex-col gap-1 rounded-lg bg-zinc-800 p-4"
16+
className="flex shrink-0 flex-col gap-1 rounded-lg bg-white dark:bg-zinc-800 p-4"
1717
>
1818
<div className="w-fit rounded-md bg-zinc-700 text-sm text-transparent">
1919
{event.date}

components/stocks/events.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ export function Events({ events }: { events: Event[] }) {
77
{events.map(event => (
88
<div
99
key={event.date}
10-
className="flex shrink-0 flex-col gap-1 rounded-lg bg-zinc-800 p-4"
10+
className="flex shrink-0 flex-col gap-1 rounded-lg bg-white dark:bg-zinc-800 p-4"
1111
>
1212
<div className="text-sm text-zinc-400">
1313
{format(parseISO(event.date), 'dd LLL, yyyy')}
1414
</div>
15-
<div className="text-base font-bold text-zinc-200">
15+
<div className="text-base font-bold text-zinc-700 dark:text-zinc-200">
1616
{event.headline}
1717
</div>
1818
<div className="text-zinc-500">

components/stocks/message.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { IconOpenAI, IconUser } from '@/components/ui/icons'
3+
import { IconOpenRouter, IconUser } from '@/components/ui/icons'
44
import { cn } from '@/lib/utils'
55
import { spinner } from './spinner'
66
import { CodeBlock } from '../ui/codeblock'
@@ -37,7 +37,7 @@ export function BotMessage({
3737
return (
3838
<div className={cn('group relative flex items-start md:-ml-12', className)}>
3939
<div className="flex size-[24px] shrink-0 select-none items-center justify-center rounded-md border bg-primary text-primary-foreground shadow-sm">
40-
<IconOpenAI />
40+
<IconOpenRouter />
4141
</div>
4242
<div className="ml-4 flex-1 space-y-2 overflow-hidden px-1">
4343
<MemoizedReactMarkdown
@@ -101,7 +101,7 @@ export function BotCard({
101101
!showAvatar && 'invisible'
102102
)}
103103
>
104-
<IconOpenAI />
104+
<IconOpenRouter className="size-4" />
105105
</div>
106106
<div className="ml-4 flex-1 pl-2">{children}</div>
107107
</div>
@@ -124,7 +124,7 @@ export function SpinnerMessage() {
124124
return (
125125
<div className="group relative flex items-start md:-ml-12">
126126
<div className="flex size-[24px] shrink-0 select-none items-center justify-center rounded-md border bg-primary text-primary-foreground shadow-sm">
127-
<IconOpenAI />
127+
<IconOpenRouter />
128128
</div>
129129
<div className="ml-4 h-[24px] flex flex-row items-center flex-1 space-y-2 overflow-hidden px-1">
130130
{spinner}

components/stocks/stock-purchase.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ export function Purchase({
6161
<div className="text-lg text-zinc-300">{symbol}</div>
6262
<div className="text-3xl font-bold">${price}</div>
6363
{purchasingUI ? (
64-
<div className="mt-4 text-zinc-200">{purchasingUI}</div>
64+
<div className="mt-4 text-zinc-700 dark:text-zinc-200">
65+
{purchasingUI}
66+
</div>
6567
) : status === 'requires_action' ? (
6668
<>
6769
<div className="relative pb-6 mt-6">

components/stocks/stock.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ export function Stock({ stock: { symbol, price, delta } }: { stock: Stock }) {
6565
)
6666

6767
return (
68-
<div className="rounded-xl border bg-zinc-950 p-4 text-green-400">
68+
<div className="rounded-xl border bg-white dark:bg-zinc-950 p-4 text-green-400">
6969
<div className="float-right inline-block rounded-full bg-white/10 px-2 py-1 text-xs">
7070
{`${delta > 0 ? '+' : ''}${((delta / price) * 100).toFixed(2)}% ${
7171
delta > 0 ? '↑' : '↓'
7272
}`}
7373
</div>
74-
<div className="text-lg text-zinc-300">{symbol}</div>
74+
<div className="text-lg text-zinc-700 dark:text-zinc-300">{symbol}</div>
7575
<div className="text-3xl font-bold">${price}</div>
7676
<div className="text mt-1 text-xs text-zinc-500">
7777
Closed: Feb 27, 4:59 PM EST
@@ -125,14 +125,14 @@ export function Stock({ stock: { symbol, price, delta } }: { stock: Stock }) {
125125
>
126126
{priceAtTime.x > 0 ? (
127127
<div
128-
className="pointer-events-none absolute z-10 flex w-fit select-none gap-2 rounded-md bg-zinc-800 p-2"
128+
className="pointer-events-none absolute z-10 flex w-fit select-none gap-2 rounded-md bg-white dark:bg-zinc-800 p-2"
129129
style={{
130130
left: priceAtTime.x - 124 / 2,
131131
top: 30
132132
}}
133133
>
134134
<div className="text-xs tabular-nums">${priceAtTime.value}</div>
135-
<div className="text-xs tabular-nums text-zinc-400">
135+
<div className="text-xs tabular-nums text-zinc-500">
136136
{priceAtTime.time}
137137
</div>
138138
</div>

components/stocks/stocks-skeleton.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
export const StocksSkeleton = () => {
22
return (
33
<div className="mb-4 flex flex-col gap-2 overflow-y-scroll pb-4 text-sm sm:flex-row">
4-
<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>
5-
<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>
6-
<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>
4+
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-white dark:bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
5+
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-white dark:bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
6+
<div className="flex h-[60px] w-full cursor-pointer flex-row gap-2 rounded-lg bg-white dark:bg-zinc-800 p-2 text-left hover:bg-zinc-800 sm:w-[208px]"></div>
77
</div>
88
)
99
}

components/stocks/stocks.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function Stocks({ stocks }: { stocks: Stock[] }) {
1515
{stocks.map(stock => (
1616
<button
1717
key={stock.symbol}
18-
className="flex cursor-pointer flex-row gap-2 rounded-lg bg-zinc-800 p-2 text-left hover:bg-zinc-700 sm:w-52"
18+
className="flex cursor-pointer flex-row gap-2 rounded-lg bg-white dark:bg-zinc-800 p-2 text-left hover:bg-zinc-700 sm:w-52"
1919
onClick={async () => {
2020
const response = await submitUserMessage(`View ${stock.symbol}`)
2121
setMessages(currentMessages => [...currentMessages, response])

components/ui/codeblock.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
9494

9595
return (
9696
<div className="relative w-full font-sans codeblock bg-zinc-950">
97-
<div className="flex items-center justify-between w-full px-6 py-2 pr-4 bg-zinc-800 text-zinc-100">
97+
<div className="flex items-center justify-between w-full px-6 py-2 pr-4 bg-white dark:bg-zinc-800 text-zinc-100">
9898
<span className="text-xs lowercase">{language}</span>
9999
<div className="flex items-center space-x-1">
100100
<Button

components/ui/icons.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ function IconOpenAI({ className, ...props }: React.ComponentProps<'svg'>) {
104104
)
105105
}
106106

107+
function IconOpenRouter({ className }: { className?: string }) {
108+
return (
109+
<svg
110+
width="512"
111+
height="512"
112+
viewBox="0 0 512 512"
113+
xmlns="http://www.w3.org/2000/svg"
114+
fill="currentColor"
115+
stroke="currentColor"
116+
className={cn('size-4', className)}
117+
>
118+
<g clip-path="url(#clip0_205_3)">
119+
<path
120+
d="M3 248.945C18 248.945 76 236 106 219C136 202 136 202 198 158C276.497 102.293 332 120.945 423 120.945"
121+
stroke-width="90"
122+
/>
123+
<path d="M511 121.5L357.25 210.268L357.25 32.7324L511 121.5Z" />
124+
<path
125+
d="M0 249C15 249 73 261.945 103 278.945C133 295.945 133 295.945 195 339.945C273.497 395.652 329 377 420 377"
126+
stroke-width="90"
127+
/>
128+
<path d="M508 376.445L354.25 287.678L354.25 465.213L508 376.445Z" />
129+
</g>
130+
</svg>
131+
)
132+
}
133+
107134
function IconVercel({ className, ...props }: React.ComponentProps<'svg'>) {
108135
return (
109136
<svg
@@ -480,6 +507,7 @@ export {
480507
IconEdit,
481508
IconNextChat,
482509
IconOpenAI,
510+
IconOpenRouter,
483511
IconVercel,
484512
IconGitHub,
485513
IconSeparator,

lib/types/tools.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const showStockPurchaseParameters = z.object({
4141
symbol: z
4242
.string()
4343
.describe(
44-
'The name or symbol of the stock or currency. e.g. DOGE/AAPL/USD.'
44+
'The name or symbol of the stock or currency. e.g. NVDA/AAPL/USD.'
4545
),
4646
price: z.number().describe('The price of the stock.'),
4747
numberOfShares: z
@@ -56,7 +56,7 @@ export const showStockPriceParameters = z.object({
5656
symbol: z
5757
.string()
5858
.describe(
59-
'The name or symbol of the stock or currency. e.g. DOGE/AAPL/USD.'
59+
'The name or symbol of the stock or currency. e.g. NVDA/AAPL/USD.'
6060
),
6161
price: z.number().describe('The price of the stock.'),
6262
delta: z.number().describe('The change in price of the stock')

0 commit comments

Comments
 (0)