Files
librechat.ai/components/Author/AuthorPage.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

93 lines
3.0 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import { getPagesUnderRoute } from 'nextra/context'
import { type Page } from 'nextra'
import { SocialIcon } from 'react-social-icons'
import Image from 'next/image'
import Link from 'next/link'
interface AuthorMetadata {
authorid: string
subtitle: string
name: string
bio: string
ogImage: string
socials?: {
[key: string]: string
}
}
const AuthorCard: React.FC<{ author: AuthorMetadata }> = ({ author }) => {
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
const socialsEntries = Object.entries(author.socials ?? {}).filter(
([, value]) => !!value,
) as unknown as [string, string][]
return (
<Link href={`/authors/${author.authorid}`}>
<div className="flex flex-col items-center gap-4 bg-gray-200/20 rounded-lg p-6 h-full group">
<div className="relative overflow-hidden rounded-full">
<Image
width={200}
height={200}
src={author.ogImage}
alt={author.name}
className="rounded-full transition-transform duration-300 ease-in-out group-hover:scale-110"
style={{ objectFit: 'cover' }}
/>
</div>
<h2 className="font-bold text-xl">{author.name}</h2>
<p className="text-sm text-center text-gray-600 grow">{author.subtitle}</p>
<div className="flex flex-wrap gap-4 justify-center mt-2">
{isClient &&
socialsEntries.map(([key, value]) => (
<a
key={key}
href={value}
className="btn btn-square relative overflow-hidden"
title={`See ${author.name}'s ${key}`}
target="_blank"
rel="noopener noreferrer"
style={{ transition: 'transform 0.3s ease' }}
onClick={(e) => e.stopPropagation()}
>
<SocialIcon
url={value}
className="absolute inset-0 size-full scale-100 transition-transform opacity-100 hover:scale-90"
bgColor="#9B9B9B80"
fgColor="background"
style={{ width: '2em', height: '2em' }}
/>
</a>
))}
</div>
</div>
</Link>
)
}
const AuthorPage: React.FC = () => {
const allAuthors = getPagesUnderRoute('/authors') as Array<Page & { frontMatter: AuthorMetadata }>
const authors = allAuthors.filter((author) => !!author.frontMatter.authorid)
return (
<section className="max-w-4xl mx-auto mt-12 mb-24 md:mb-32">
<h1 className="font-extrabold text-3xl lg:text-5xl tracking-tight mb-8 text-center">
Our Authors
</h1>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
{authors.map((author) => (
<AuthorCard key={author.frontMatter.authorid} author={author.frontMatter} />
))}
</div>
</section>
)
}
export default AuthorPage