mirror of
https://github.com/dergigi/boris.git
synced 2026-01-17 13:54:24 +01:00
- Make AuthorCard clickable to navigate to user profiles - Add /p/:npub and /p/:npub/writings routes - Reuse Me component for public profiles with pubkey prop - Show highlights and writings tabs for any user - Hide private tabs (reading-list, archive) on public profiles - Public profiles show only public data (highlights, writings) - Private data (bookmarks, read articles) only visible on own profile - Add clickable author card hover styles with indigo border - Decode npub to pubkey for profile viewing - DRY: Single Me component serves both /me and /p/:npub routes
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import React from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
import { faUserCircle } from '@fortawesome/free-solid-svg-icons'
|
|
import { useEventModel } from 'applesauce-react/hooks'
|
|
import { Models } from 'applesauce-core'
|
|
import { nip19 } from 'nostr-tools'
|
|
|
|
interface AuthorCardProps {
|
|
authorPubkey: string
|
|
clickable?: boolean
|
|
}
|
|
|
|
const AuthorCard: React.FC<AuthorCardProps> = ({ authorPubkey, clickable = true }) => {
|
|
const navigate = useNavigate()
|
|
const profile = useEventModel(Models.ProfileModel, [authorPubkey])
|
|
|
|
const getAuthorName = () => {
|
|
if (profile?.name) return profile.name
|
|
if (profile?.display_name) return profile.display_name
|
|
return `${authorPubkey.slice(0, 8)}...${authorPubkey.slice(-8)}`
|
|
}
|
|
|
|
const authorImage = profile?.picture || profile?.image
|
|
const authorBio = profile?.about
|
|
|
|
const handleClick = () => {
|
|
if (clickable) {
|
|
const npub = nip19.npubEncode(authorPubkey)
|
|
navigate(`/p/${npub}`)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={`author-card ${clickable ? 'author-card-clickable' : ''}`}
|
|
onClick={handleClick}
|
|
style={clickable ? { cursor: 'pointer' } : undefined}
|
|
>
|
|
<div className="author-card-avatar">
|
|
{authorImage ? (
|
|
<img src={authorImage} alt={getAuthorName()} />
|
|
) : (
|
|
<FontAwesomeIcon icon={faUserCircle} />
|
|
)}
|
|
</div>
|
|
<div className="author-card-content">
|
|
<div className="author-card-name">{getAuthorName()}</div>
|
|
{authorBio && (
|
|
<p className="author-card-bio">{authorBio}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default AuthorCard
|
|
|