Files
librechat.ai/components/home/Changelog.tsx
Danny Avila a0a74501c9 chore: bump dev packages, linting, logos (#521)
* chore: upgrade eslint to v9

* chore: update package dependencies in package.json and pnpm-lock.yaml

- Added `minimatch` and `serialize-javascript` dependencies with updated versions.
- Upgraded `ajv` to version 6.14.0.
- Removed outdated dependencies from pnpm-lock.yaml for better package management.

* feat: add Stripe logos to Companies section

- Introduced new company entry for Stripe in the Companies component, including both light and dark logo variants.
- Updated the Companies array to display 10 logos instead of 8.
- Adjusted TypeScript environment reference to point to the development types directory.
2026-03-02 18:18:50 -05:00

106 lines
4.1 KiB
TypeScript

import { cn } from '@/lib/utils'
import Link from 'next/link'
import { Page } from 'nextra'
import { getPagesUnderRoute } from 'nextra/context'
const changelogItems = getPagesUnderRoute('/changelog') as Array<Page & { frontMatter: any }>
export default function Changelog({ className }: { className?: string }) {
const changelog = changelogItems
.filter(
(page) =>
page.route &&
!page.route.includes('content') &&
page.frontMatter.title &&
page.frontMatter.date,
)
.sort((a, b) => new Date(b.frontMatter.date).getTime() - new Date(a.frontMatter.date).getTime())
.slice(0, 20)
.map(({ route, frontMatter }) => ({
route,
title: frontMatter.title ?? null,
author: frontMatter.author ?? null,
date: new Date(frontMatter.date),
}))
return (
<div
className={cn('rounded border p-5 max-w-lg mx-5 sm:mx-auto', className)}
role="region" // Added role for the container
aria-labelledby="changelog-heading" // Added aria-labelledby to reference the heading
>
<div className="px-5 py-2 text-center -mt-5 -mx-5 mb-5 border-b font-medium">
<h3 id="changelog-heading">Changelog</h3> {/* Added id to the heading */}
</div>
<div
role="list"
className="space-y-6 max-h-52 lg:max-h-96 overflow-y-scroll"
aria-label="Recent changelog entries" // Added aria-label for the list
>
{changelog.map((activityItem) => (
<Link
href={activityItem.route}
className="relative flex gap-x-4 group"
key={activityItem.route}
role="listitem" // Added role for each list item
aria-label={`Changelog entry for ${activityItem.title}`} // Added aria-label for each list item
>
<div className="-bottom-6 absolute left-0 top-0 flex w-6 justify-center">
<div className="w-px bg-secondary" />
</div>
<div className="relative flex size-6 flex-none items-center justify-center bg-background">
<div className="size-1.5 rounded-full bg-secondary ring-1 ring-primary/80 opacity-60 group-hover:opacity-100" />
</div>
<p className="flex-auto py-0.5 text-sm leading-5 text-primary/70 opacity-80 group-hover:opacity-100">
<span className="font-medium text-primary">{activityItem.title}</span>{' '}
{activityItem.author ? `by ${activityItem.author}` : null}
</p>
{activityItem.date ? (
<time
dateTime={activityItem.date.toISOString()}
className="flex-none py-0.5 text-sm leading-5 text-primary/70 opacity-80 group-hover:opacity-100"
aria-label={`Date: ${formatDate(activityItem.date)}`} // Added aria-label for the date
>
{formatDate(activityItem.date)}
</time>
) : null}
</Link>
))}
</div>
<Link
key="root"
href="/changelog"
className="relative flex gap-x-4 group"
role="button" // Added role for the link acting as a button
aria-label="Read the full changelog" // Added aria-label for the link
>
<div className="size-6 absolute left-0 top-0 flex justify-center">
<div className="w-px bg-secondary" />
</div>
<div className="relative flex size-6 flex-none items-center justify-center bg-background">
<div className="size-1.5 rounded-full bg-secondary ring-1 ring-primary/80 opacity-60 group-hover:opacity-100" />
</div>
<p className="flex-auto py-0.5 text-sm leading-5 text-primary/60 opacity-80 group-hover:opacity-100">
<span className="font-medium text-primary">Read the full changelog ...</span> {null}
</p>
</Link>
</div>
)
}
function formatDate(date: Date) {
const dayDiff = (Date.now() - date.getTime()) / (1000 * 60 * 60 * 24)
if (dayDiff < 1) return 'today'
if (dayDiff < 14) return `${Math.round(dayDiff)} days ago`
return date.toLocaleDateString(undefined, {
month: 'short',
day: 'numeric',
year: 'numeric',
timeZone: 'UTC',
})
}