Files
awesome-app/components/readme/readme-header.tsx
valknarness b63592f153 a new start
2025-10-25 16:09:02 +02:00

137 lines
4.7 KiB
TypeScript

'use client'
import * as React from 'react'
import Link from 'next/link'
import { Star, Share2, ExternalLink, Copy, Mail, MessageSquare } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { toast } from 'sonner'
interface ReadmeHeaderProps {
metadata: {
title: string
description: string
stars: number
lastUpdated: string
url: string
}
}
export function ReadmeHeader({ metadata }: ReadmeHeaderProps) {
const [isSticky, setIsSticky] = React.useState(false)
React.useEffect(() => {
const handleScroll = () => {
setIsSticky(window.scrollY > 100)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
const handleCopyLink = async () => {
try {
await navigator.clipboard.writeText(window.location.href)
toast.success('Link copied to clipboard!')
} catch (error) {
toast.error('Failed to copy link')
}
}
const handleShare = (type: 'twitter' | 'email' | 'reddit') => {
const url = encodeURIComponent(window.location.href)
const text = encodeURIComponent(`Check out ${metadata.title}: ${metadata.description}`)
const shareUrls = {
twitter: `https://twitter.com/intent/tweet?text=${text}&url=${url}`,
email: `mailto:?subject=${encodeURIComponent(metadata.title)}&body=${text}%20${url}`,
reddit: `https://reddit.com/submit?url=${url}&title=${encodeURIComponent(metadata.title)}`,
}
window.open(shareUrls[type], '_blank', 'noopener,noreferrer')
}
return (
<header
className={`sticky top-0 z-50 border-b transition-all duration-300 ${
isSticky
? 'bg-background/95 shadow-lg backdrop-blur-sm'
: 'bg-background/80 backdrop-blur-sm'
}`}
>
<div className="mx-auto max-w-7xl px-6 py-4">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
{/* Left side */}
<div className="flex-1">
<h1 className="gradient-text mb-2 text-2xl font-bold sm:text-3xl">
{metadata.title}
</h1>
<p className="text-sm text-muted-foreground sm:text-base">
{metadata.description}
</p>
</div>
{/* Right side - Actions */}
<div className="flex flex-wrap items-center gap-2">
{/* Stars */}
<div className="flex items-center gap-1.5 rounded-lg border border-primary/20 bg-primary/10 px-3 py-2 text-sm font-medium text-primary">
<Star className="h-4 w-4 fill-current" />
<span>{metadata.stars.toLocaleString()}</span>
</div>
{/* Share Button */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="default" className="gap-2">
<Share2 className="h-4 w-4" />
<span className="hidden sm:inline">Share</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={handleCopyLink}>
<Copy className="mr-2 h-4 w-4" />
Copy Link
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleShare('twitter')}>
<MessageSquare className="mr-2 h-4 w-4" />
Share on Twitter
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleShare('reddit')}>
<MessageSquare className="mr-2 h-4 w-4" />
Share on Reddit
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleShare('email')}>
<Mail className="mr-2 h-4 w-4" />
Share via Email
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* GitHub Link */}
<Button asChild variant="default" size="default" className="gap-2">
<Link href={metadata.url} target="_blank" rel="noopener noreferrer">
<ExternalLink className="h-4 w-4" />
<span className="hidden sm:inline">View on GitHub</span>
</Link>
</Button>
</div>
</div>
{/* Last updated */}
<div className="mt-2 text-xs text-muted-foreground">
Last updated: {new Date(metadata.lastUpdated).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</div>
</div>
</header>
)
}