Add frontend components for project/package/tag hierarchy views
- Create reusable UI components: Badge, Breadcrumb, Card, DataTable, FilterChip, Pagination, SearchInput, SortDropdown - Update Home page with search, sort, filter, and pagination - Update ProjectPage with package stats, format filtering, keyboard nav - Update PackagePage with DataTable for tags, copy artifact ID, metadata - Add TypeScript types for paginated responses and list params - Update API client with pagination and filter query param support - URL-based state persistence for all filter/sort/page params - Keyboard navigation (Backspace to go up hierarchy)
This commit is contained in:
59
frontend/src/components/Card.tsx
Normal file
59
frontend/src/components/Card.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { ReactNode } from 'react';
|
||||
import './Card.css';
|
||||
|
||||
interface CardProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
href?: string;
|
||||
variant?: 'default' | 'elevated' | 'accent';
|
||||
}
|
||||
|
||||
export function Card({ children, className = '', onClick, href, variant = 'default' }: CardProps) {
|
||||
const baseClass = `card card--${variant} ${className}`.trim();
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<a href={href} className={`${baseClass} card--clickable`}>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
return (
|
||||
<div className={`${baseClass} card--clickable`} onClick={onClick} role="button" tabIndex={0}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className={baseClass}>{children}</div>;
|
||||
}
|
||||
|
||||
interface CardHeaderProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function CardHeader({ children, className = '' }: CardHeaderProps) {
|
||||
return <div className={`card__header ${className}`.trim()}>{children}</div>;
|
||||
}
|
||||
|
||||
interface CardBodyProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function CardBody({ children, className = '' }: CardBodyProps) {
|
||||
return <div className={`card__body ${className}`.trim()}>{children}</div>;
|
||||
}
|
||||
|
||||
interface CardFooterProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function CardFooter({ children, className = '' }: CardFooterProps) {
|
||||
return <div className={`card__footer ${className}`.trim()}>{children}</div>;
|
||||
}
|
||||
Reference in New Issue
Block a user