Skip to content

Commit

Permalink
fix: included lib in gitignore and added lib files
Browse files Browse the repository at this point in the history
  • Loading branch information
broomva committed Mar 15, 2024
1 parent 8f99d00 commit 0c23992
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
62 changes: 62 additions & 0 deletions src/lib/analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { NextApiRequest } from 'next'
import type { NextFetchEvent, NextRequest } from 'next/server'

export const initAnalytics = ({
request,
event
}: {
request: NextRequest | NextApiRequest | Request
event?: NextFetchEvent
}) => {
const endpoint = process.env.VERCEL_URL

return {
track: async (eventName: string, data?: any) => {
try {
if (!endpoint && process.env.NODE_ENV === 'development') {
console.log(
`[Vercel Web Analytics] Track "${eventName}"` +
(data ? ` with data ${JSON.stringify(data || {})}` : '')
)
return
}

const headers: { [key: string]: string } = {}
Object.entries(request.headers).map(([key, value]) => {
headers[key] = value
})

const body = {
o: headers.referer,
ts: new Date().getTime(),
r: '',
en: eventName,
ed: data
}

const promise = fetch(
`https://${process.env.VERCEL_URL}/_vercel/insights/event`,
{
headers: {
'content-type': 'application/json',
'user-agent': headers['user-agent'] as string,
'x-forwarded-for': headers['x-forwarded-for'] as string,
'x-va-server': '1'
},
body: JSON.stringify(body),
method: 'POST'
}
)

if (event) {
event.waitUntil(promise)
}
{
await promise
}
} catch (err) {
console.error(err)
}
}
}
}
11 changes: 11 additions & 0 deletions src/lib/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { JetBrains_Mono as FontMono, Inter as FontSans } from 'next/font/google'

export const fontSans = FontSans({
subsets: ['latin'],
variable: '--font-sans'
})

export const fontMono = FontMono({
subsets: ['latin'],
variable: '--font-mono'
})
23 changes: 23 additions & 0 deletions src/lib/hooks/use-at-bottom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react'

export function useAtBottom(offset = 0) {
const [isAtBottom, setIsAtBottom] = React.useState(false)

React.useEffect(() => {
const handleScroll = () => {
setIsAtBottom(
window.innerHeight + window.scrollY >=
document.body.offsetHeight - offset
)
}

window.addEventListener('scroll', handleScroll, { passive: true })
handleScroll()

return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [offset])

return isAtBottom
}
33 changes: 33 additions & 0 deletions src/lib/hooks/use-copy-to-clipboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use client'

import * as React from 'react'

export interface useCopyToClipboardProps {
timeout?: number
}

export function useCopyToClipboard({
timeout = 2000
}: useCopyToClipboardProps) {
const [isCopied, setIsCopied] = React.useState<Boolean>(false)

const copyToClipboard = (value: string) => {
if (typeof window === 'undefined' || !navigator.clipboard?.writeText) {
return
}

if (!value) {
return
}

navigator.clipboard.writeText(value).then(() => {
setIsCopied(true)

setTimeout(() => {
setIsCopied(false)
}, timeout)
})
}

return { isCopied, copyToClipboard }
}
23 changes: 23 additions & 0 deletions src/lib/hooks/use-enter-submit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useRef, type RefObject } from 'react'

export function useEnterSubmit(): {
formRef: RefObject<HTMLFormElement>
onKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void
} {
const formRef = useRef<HTMLFormElement>(null)

const handleKeyDown = (
event: React.KeyboardEvent<HTMLTextAreaElement>
): void => {
if (
event.key === 'Enter' &&
!event.shiftKey &&
!event.nativeEvent.isComposing
) {
formRef.current?.requestSubmit()
event.preventDefault()
}
}

return { formRef, onKeyDown: handleKeyDown }
}
24 changes: 24 additions & 0 deletions src/lib/hooks/use-local-storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useEffect, useState } from 'react'

export const useLocalStorage = <T>(
key: string,
initialValue: T
): [T, (value: T) => void] => {
const [storedValue, setStoredValue] = useState(initialValue)

useEffect(() => {
// Retrieve from localStorage
const item = window.localStorage.getItem(key)
if (item) {
setStoredValue(JSON.parse(item))
}
}, [key])

const setValue = (value: T) => {
// Save state
setStoredValue(value)
// Save to localStorage
window.localStorage.setItem(key, JSON.stringify(value))
}
return [storedValue, setValue]
}
18 changes: 18 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type Message } from 'ai'

export interface Chat extends Record<string, any> {
id: string
title: string
createdAt: Date
userId: string
path: string
messages: Message[]
sharePath?: string
}

export type ServerActionResult<Result> = Promise<
| Result
| {
error: string
}
>
43 changes: 43 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { clsx, type ClassValue } from 'clsx'
import { customAlphabet } from 'nanoid'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

export const nanoid = customAlphabet(
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
7
) // 7-character random string

export async function fetcher<JSON = any>(
input: RequestInfo,
init?: RequestInit
): Promise<JSON> {
const res = await fetch(input, init)

if (!res.ok) {
const json = await res.json()
if (json.error) {
const error = new Error(json.error) as Error & {
status: number
}
error.status = res.status
throw error
} else {
throw new Error('An unexpected error occurred')
}
}

return res.json()
}

export function formatDate(input: string | number | Date): string {
const date = new Date(input)
return date.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric'
})
}

0 comments on commit 0c23992

Please sign in to comment.