veza/apps/web/src/features/dashboard/components/RecentTracksCard.tsx

94 lines
3.3 KiB
TypeScript

import { Music } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader } from '@/components/ui/card';
import { ContentTransition } from '@/components/ui/content-transition';
import { useTranslation } from '@/hooks/useTranslation';
import { Link } from 'react-router-dom';
interface LibraryItem {
id: string;
title: string;
description?: string;
}
interface SectionHeaderProps {
title: string;
viewAllPath?: string;
}
function SectionHeader({ title, viewAllPath }: SectionHeaderProps) {
const { t } = useTranslation();
return (
<div className="flex items-center justify-between mb-4">
<h2 className="text-heading-3">{title}</h2>
{viewAllPath && (
<Link
to={viewAllPath}
className="text-caption hover:text-foreground transition-colors"
>
{t('dashboard.viewAll')}
</Link>
)}
</div>
);
}
interface RecentTracksCardProps {
items: LibraryItem[];
isLoading: boolean;
}
export function RecentTracksCard({ items, isLoading }: RecentTracksCardProps) {
const { t } = useTranslation();
return (
<Card variant="glass">
<CardHeader>
<SectionHeader title={t('dashboard.recentTracks')} viewAllPath="/library" />
<CardDescription>
{t('dashboard.recentTracksDescription')}
</CardDescription>
</CardHeader>
<CardContent>
<ContentTransition
isLoading={isLoading}
skeleton={
<div className="space-y-4">
{[...Array(3)].map((_, i) => (
<div key={i} className="flex items-center space-x-4 animate-pulse">
<div className="w-10 h-10 bg-muted rounded" />
<div className="flex-1 space-y-2">
<div className="h-3 bg-muted rounded w-3/4" />
<div className="h-2 bg-muted rounded w-1/2" />
</div>
</div>
))}
</div>
}
>
<div className="space-y-4">
{items.slice(0, 3).map((item) => (
<div key={item.id} className="flex items-center space-x-4 p-2 rounded-lg hover:bg-white/5 transition-colors duration-[var(--duration-fast)] cursor-pointer group border border-transparent hover:border-white/5">
<div className="w-10 h-10 bg-muted/50 rounded flex items-center justify-center border border-border group-hover:border-primary/50 transition-colors shadow-lg">
<Music className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" />
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium truncate text-foreground group-hover:text-primary transition-colors">
{item.title}
</p>
<p className="text-xs text-muted-foreground truncate group-hover:text-foreground/80">
{item.description || 'No description'}
</p>
</div>
</div>
))}
{items.length === 0 && (
<p className="text-sm text-muted-foreground text-center py-8">
{t('dashboard.noTracksInLibrary')}
</p>
)}
</div>
</ContentTransition>
</CardContent>
</Card>
);
}